2

テストを書いた後this、インターフェイスのポインターが具象クラスのポインターと等しくないことがわかりましたthis。つまり、C スタイルのキャストをそのまま使用することはできません。

class AbstractBase {...};

class AnInterface {
public:
    AnInterface() {...} // need AbstractBase * here 
    ~virtual AnInterface() {...} // and here
};

class Concrete : public AbstractBase, public AnInterface {};

私のインターフェイスには、インターフェイス関連の登録と登録解除を処理するために、コンストラクターとデストラクタでそれを継承する具象クラスへの基本クラス ポインターが必要です。

インターフェイスを継承するすべての具体的なオブジェクトは、最初に抽象基本クラスを継承する必要があります。これは常にレイアウトの最初です。

コンストラクターについては、それほど難しいことではありません。インターフェイス コンストラクターにポインターを追加してthis、具象クラスから渡すことができます。しかし、デストラクタにはパラメータがないため、暗闇の中にいます。

これまでに思いついたソリューションにはオーバーヘッドが伴います。

1 - デストラクタで使用されるインターフェイスにポインタを格納します - 1 つのポインタに相当するメモリ オーバーヘッドを追加します

class AnInterface {
public:
    AnInterface(AbstractBase * ap) {...}
    ~virtual AnInterface() {...} // and here
private:
    AbstractBase * aPtr;
};

...
Concrete() : AnInterface(this) {}

2 - インターフェイスに抽象メソッドを作成thisし、具象クラスに返すように実装します - 仮想呼び出しの間接的なオーバーヘッドを追加します

class AnInterface {
    virtual AbstractBase * getPtr() = 0;
};

class Concrete : public AbstractBase, public AnInterface {
    AbstractBase * getPtr() { return this; }
};

3 - dynamic_castさらに悪い

これを達成するためのより効率的な方法はありますか?

4

3 に答える 3

1

あなたのデザインにはいくつかの欠陥があります。

Mixin アスペクトから CRTP を使用することを検討する必要があります。これにより、派生したコンクリートの余分なポインターを保持する必要がなくなります。

template<typename Derived>
class AnInterface {
public:
    AnInterface() {
       Derived* derived = static_cast<Derived*>(this);
       AbstractBase* abstractBase = static_cast<AbstractBase*>(derived);
    } // have AbstractBase * here 
    ~virtual AnInterface() {...} // and here
};

class Concrete 
: public virtual AbstractBase
, public AnInterface<Concrete> {
    AbstractBase * getPtr() { return this; }
};
于 2015-03-16T20:38:21.100 に答える