5

我正在尝试围绕连接指针编写一个简单的包装器,当包装器被销毁时,它将把它返回到池中,但它不会编译,因为 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);
    }
};
4

7 回答 7

6

A combination of forward declaration and separation of declaration from definition of members with circular dependencies works. For example:

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);
}
于 2010-03-15T13:23:53.593 回答
4

使用前向声明:

class Connection {};

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

class AutoConn {
//definitions
};

class ConnectionPool {
//definitions
};
于 2010-03-15T13:18:05.073 回答
3

在定义类之后实现函数

于 2010-03-15T13:18:23.620 回答
3

前向声明的正确语法是:

class Connection; // no {}

如果你写

class Connection {};

然后你在定义类,你不能定义一个类两次。

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

于 2010-03-15T13:19:28.370 回答
1

Forward declaration only tells the compiler "such a class exists". In your

AutoConn getConn()

since AutoConn is a value type, the whole structure of AutoConn must be known, so forward declaration of the class won't work. So you must put the actual declaration of AutoConn before ConnectionPool.

In your AutoConn, the type ConnectionPool is only referred by pointers. In this case the whole structure of ConnectionPool is not required, so forward declaration of ConnectionPool is enough.

Therefore you need to rearrangement the classes into this:

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

But notice that

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

these methods require the compiler to know the members of ConnectionPool, so a complete structure is needed. To solve this problem the definition must be placed after ConnectionPool. Thus only the constructors and destructors should remain.

class AutoConn {
  ...
  AutoConn(ConnectionPool* pool, Connection *c);
  ~AutoConn();
}
class ConnectionPool { ... };
AutoConn::AutoConn(ConnectionPool* pool, Connection *c) : ... { ... }
AutoConn::~AutoConn() { ... }
于 2010-03-15T13:22:43.063 回答
0

您可能希望将 allConnectionPoolAutoConn方法的定义外包,即

class ConnectionPool;
class AutoConn {…};

class ConnectionPool {…};

AutoConn ConnectionPool::getConn() {
   …
}
于 2010-03-15T13:18:52.370 回答
0

不要ConnectionPoolAutoConn. 只需使用头文件class ConnectionPool;中的前向引用即可。AutoConn

于 2010-03-15T13:20:02.707 回答