2
#include<iostream>
using namespace std;

class base
{
    public:
      virtual void f(){}
};

class middle1:public base
{};

class middle2:public base
{};

class derive:public middle1,public middle2
{};



int main()
{
    derive* pd=new derive();
    pd->f();
    return 0;
}

仮想がこの問題を解決することは知っていますが、どうすればよいでしょうか? 多重継承がなくても、安全のために public virtual を常に記述できますか。

4

3 に答える 3

5

Each instance of derive has a middle1 base class sub-object and a middle2 base class sub-object.

If the inheritance is non-virtual, then the middle1 base class sub-object has a base base class subobject, and the middle2 base class sub-object also has a base base class sub-object. Hence, each instance of derive has two base sub-objects, and the call pd->f() is ambiguous -- which of the base objects do you want to call f() on?

Making the inheritance virtual means that middle1 and middle2 will share a single base sub-object of derive. This removes the ambiguity -- there is only one base object that f() could be called on.

Can we always write public virtual for safety

Not necessarily. There may be inheritance hierarchies in which you don't want middle1 and middle2 to share a public base sub-object. You could probably argue that in such cases, you shouldn't be writing a class derive that inherits from both, but if you do end up with that situation then the workaround would be to do either:

static_cast<middle1*>(pd)->f();
pd->middle1::f();

to specify that you want to call f on the middle1 base class sub-object, or

static_cast<middle2*>(pd)->f();
pd->middle2::f();

to specify middle2.

于 2013-03-19T11:39:43.713 に答える
1

仮想がこの問題を解決することは知っていますが、どうすればよいでしょうか?

virtualキーワードは、継承階層に最上位の基底クラス サブオブジェクトを 1 つだけ存在させることで問題を解決します。middle1それがないと、各親クラスmiddle2が独自のbaseクラスのコピーを持つため、あいまいさが生じます。

多重継承がなくても、安全のために public virtual を常に記述できますか。

virtual多重継承がない場合、継承を使用する理由はありません。多重継承は、仮想継承の概念が存在する目的です。

于 2013-03-19T11:36:50.250 に答える
1

仮想基本クラスは、ひし形の問題を解決するために追加の間接レベルを実装します (この質問を参照してください)。

常に仮想継承を使用すると、追加の間接化レベルによるパフォーマンスの低下が常に発生します。

したがって、必要な場合にのみ仮想継承を使用することをお勧めします。

于 2013-03-19T11:38:11.043 に答える