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

前方宣言と、循環依存を持つメンバーの定義からの宣言の分離の組み合わせが機能します。例えば:

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 {};

次に、クラスを定義しているので、クラスを2回定義することはできません。

また、あなたは前向きに宣言するべきではありませAutoConnConnectionか?

于 2010-03-15T13:19:28.370 に答える
1

前方宣言は、コンパイラに「そのようなクラスが存在する」ことだけを伝えます。あなたの中で

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() { ... }
于 2010-03-15T13:22:43.063 に答える
0

すべてConnectionPoolAutoConnメソッドの定義を外部委託することをお勧めします。

class ConnectionPool;
class AutoConn {…};

class ConnectionPool {…};

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

ConnectionPoolにヘッダーファイルを含めないでくださいAutoConn。ヘッダーファイルclass ConnectionPool;のように前方参照を使用するだけです。AutoConn

于 2010-03-15T13:20:02.707 に答える