2

これは Python と C++ の質問です。

私は複数の継承を試していますが、この例に出くわしました。

B1 B2
 \ /
  D

2 つの (独立した?) 親クラスB1, B2と 1 つの子クラスがあるとしDます。のオブジェクトのみに関心がありますclass D

class B1:
    def f1(self):
        print "In f1"

class B2:
    def f2(self):
        self.f1()

class D (B1, B2):
    def fD(self):
        self.f2()

d = D()
d.fD()

Output: In f1

(少なくとも私にとって)興味深いのは、それclass B2についての知識がなくclass B1ても、問題なくf2呼び出すことができるということです。self.f1()

f1私はこれを正確に C++ で複製しようとしましたが、から呼び出す方法がわからないため、機能させることができませんでしたf2

class B1 {
    public:
    virtual ~B1() {}
    virtual void f1() { cout << "In f1" << endl; }
};

class B2 {
    public:
    virtual ~B2() {}
    virtual void f2() { /* What goes here?? */ }
};

class D : public B1, public B2 {
    public:
    void fD() { f2(); }
};

だから、Pythonがこれを処理できるのに、C++ができない理由/方法を知りたいですか?

また、C++ コードを Python コードのように動作させるには、どのような最小限の変更を加えることができますか?

4

3 に答える 3

1

f1クラス内の名前はB2実行時に解決されるため、これは Python で機能します。これは「ダックタイピング」です。 のオブジェクト参照にselfは有効なf1呼び出しが必要であり、そのように構築すると有効になります。

C++ で同様の動作を得る最も C++ らしい方法は、Curiously recurring template patternです。の C++ バージョンB2は、それが何の一部であるかを知る必要があります。それを派生型のテンプレートにすることで、他のdynamic_cast人が提案したことを行うための「クリーンな」方法が得られます。B2<T>そこから派生するすべてのクラスに新しいクラスがあるため、よりクリーンです。各専門化にf2は、適切なキャストを使用して適切なキャストを使用する個別がありますf1。callable の存在が必要なすべてであるという点で、Python バージョンと同じように機能しf1ます (ただし、実行時ではなくコンパイル時)。

class B1 {
    public:
    virtual ~B1() {}
    virtual void f1() { cout << "In f1" << endl; }
};

template <typename Derived>
class B2 {
    public:
    virtual ~B2() {}
    virtual void f2() { dynamic_cast<Derived *>(this)->f1(); }
};

class D : public B1, public B2<D> {
    public:
    void fD() { f2(); }
};
于 2013-07-21T05:53:22.600 に答える
1

C++ コードを Python コードのように動作させるには、どのような最小限の変更を加えることができますか?

簡単な答え: できません。 スーパークラスとしてB2も持つサブクラスの一部を形成することになるとは思いもしません。B1

長い答え:this汚いダウンキャスト (本質的に a へのキャスト) を使用すれば、可能ですD*。しかし、必ずしもそうではないので、おそらく良い考えで*thisはありませんD

于 2013-07-21T04:57:27.253 に答える