簡體   English   中英

當兩個類相互引用時編譯C ++

[英]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的實際聲明。

AutoConnConnectionPool類型僅由指針引用。 在這種情況下,不需要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() {
   …
}

不要在AutoConn包含ConnectionPool頭文件。 只需使用class ConnectionPool;的前向引用class ConnectionPool; AutoConn頭文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM