2

私は長い間、これを行うためのクリーンな方法を探しています。私の問題では、親を共有していないが、それぞれが同じ名前のメソッド(A.doSomething、B.doSomething、C.doSomething)を持つ3つのクラスが存在します。したがって、同じ関数シグネチャを持ち、Aから継承し、メソッドdoSomething()を使用するクラスDは、BまたはCから継承するEと「同じように見えます」。

これが私がやりたいことのスケッチです:

class Base {
    public:
    void myMethod(void) { doSomething(); }
};

class Independent {
    public:
        doSomething();
};

clase Derived : public Base : public Independent {
 (...)
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}

この問題では、タイプ「Independent」のオブジェクトが、変更できないライブラリによって提供されています。後で継承されるメソッドを使用する基本クラスを定義したいと思います。あいまいなコンパイルを行わずに、仮想継承を使用してこれを行う適切な方法を見つけることができませんでした。

4

1 に答える 1

5

あなたはそこに厄介な状況を持っています。これに対する 1 つの解決策は、Curiously Recurring Template パターンを使用して、次のようにコンパイル時に継承を実行することです。

template <typename D>
class Base {
    public:
        void myMethod(void) { static_cast<D*>(this)->doSomething(); }
};

class Independent {
    public:
        void doSomething();
};

clase Derived : public Base : public Independent {
    /*...*/
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}

または、仲介者クラスを間に配置して転送することもできますIndependent(同じBaseandから派生した多くのクラスがありIndependent、クラスごとにこれを行う必要はないと思います)。

template <typename D>
class Base {
    private:
        virtual void doSomethingImpl();
    public:
        void myMethod(void) { doSomethingImpl(); }
};

class Independent {
    public:
        void doSomething();
};

class IndependentWrapper : public Base : public Independent {
    private:
        void doSomethingImpl() { Independent::doSomething(); }
};

clase Derived : public IndependentWrapper {
    /*...*/
};

int main(void) {
   Derived *derivedObject = new Derived();
   derivedObject->myMethod();
}
于 2009-06-18T03:16:11.127 に答える