当两个类互相引用时编译 C++
-
20-09-2019 - |
题
我正在尝试围绕连接指针编写一个简单的包装器,当包装器被销毁时,该包装器会将其返回到池中,但它不会编译,因为 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() { ... }
您可能希望外包的所有ConnectionPool
和AutoConn
方法的定义,即。
class ConnectionPool;
class AutoConn {…};
class ConnectionPool {…};
AutoConn ConnectionPool::getConn() {
…
}
不包括在ConnectionPool
AutoConn
头文件。只要使用像在class ConnectionPool;
头文件AutoConn
前向参考。
不隶属于 StackOverflow