我正在尝试围绕连接指针编写一个简单的包装器,当包装器被销毁时,该包装器会将其返回到池中,但它不会编译,因为 ConnectionPool 和 AutoConn 需要彼此声明。

我尝试使用前向减速,但没有成功。我该如何解决这个问题?(使用g++)

class Connection {};

class ConnectionPool
{
    Connection *m_c;
public: 
    AutoConn getConn()
    {
        return AutoConn(this, m_c); // by value
    }

    void releaseConnection(Connection *c)
    {
    }
};

class AutoConn
{
    ConnectionPool* m_pool;
    Connection *m_connection;
public:
    AutoConn(ConnectionPool* pool, Connection *c) : m_pool(pool), m_connection(c) {}
    ~AutoConn()
    {
        m_pool->releaseConnection(m_connection);
    }
};
有帮助吗?

解决方案

向前声明和从与循环依赖作品成员的定义声明的分离的组合。例如:

class Connection {};
class ConnectionPool ;

class AutoConn
{

    ConnectionPool* m_pool;
    Connection *m_connection;
public:
    AutoConn(ConnectionPool* pool, Connection *c) : m_pool(pool), m_connection(c) {}
    ~AutoConn() ;  // Not defined here because it accesses unknown members of class Connection
} ;

class ConnectionPool
{
    Connection *m_c;
public: 
    AutoConn getConn()
    {
        return AutoConn(this, m_c); // by value
    }

    void releaseConnection(Connection *c)
    {
    }
};

// Definition of destructor with class Connection member dependencies.
AutoConn::~AutoConn()
{
    m_pool->releaseConnection(m_connection);
}

其他提示

使用前向声明:

class Connection {};

class ConnectionPool; //<<<<<<<<<<<<<<<forward declaration

class AutoConn {
//definitions
};

class ConnectionPool {
//definitions
};

实现,其中类别被定义的点之后的功能

前向声明的正确语法是:

class Connection; // no {}

如果你写

class Connection {};

然后就是定义类了,一个类不能定义两次。

另外,你不应该提前声明吗? AutoConn, , 不是 Connection?

转发声明只告诉编译器“这样的类是否存在”。在

AutoConn getConn()

因为AutoConn是值类型,AutoConn的整体结构必须是已知的,所述类的这样的前向声明将不起作用。所以,你必须把AutoConn的实际申报ConnectionPool之前。

在您的AutoConn,类型ConnectionPool仅由指针所指。在这种情况下,不需要ConnectionPool的整体结构,ConnectionPool的向前如此声明是不够的。

因此需要将类重排为这样:

class Connection;
class ConnectionPool;
class AutoConn { ... };
class ConnectionPool { ... };

但是请注意,

AutoConn(ConnectionPool* pool, Connection *c) : m_pool(pool), m_connection(c) {}
~AutoConn()
{
    m_pool->releaseConnection(m_connection);
}

这些方法需要编译器知道ConnectionPool的成员,因此需要一个完整的结构。为了解决这个问题的定义必须放在ConnectionPool后。因此,只有在构造和析构应保持。

class AutoConn {
  ...
  AutoConn(ConnectionPool* pool, Connection *c);
  ~AutoConn();
}
class ConnectionPool { ... };
AutoConn::AutoConn(ConnectionPool* pool, Connection *c) : ... { ... }
AutoConn::~AutoConn() { ... }

您可能希望外包的所有ConnectionPoolAutoConn方法的定义,即。

class ConnectionPool;
class AutoConn {…};

class ConnectionPool {…};

AutoConn ConnectionPool::getConn() {
   …
}

不包括在ConnectionPool AutoConn头文件。只要使用像在class ConnectionPool;头文件AutoConn前向参考。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top