[英]Compiling C++ when two classes refer to one another
我試圖圍繞一個連接指針編寫一個簡單的包裝器,當包裝器被銷毀時它會將它返回到池中,但它不會編譯,因為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
的整個結構,因此該類的前向聲明將不起作用。 因此,您必須在ConnectionPool
之前放置AutoConn
的實際聲明。
在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() {
…
}
不要在AutoConn
包含ConnectionPool
頭文件。 只需使用class ConnectionPool;
的前向引用class ConnectionPool;
在AutoConn
頭文件中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.