型階層のコンストラクタの呼び出しのルールに厄介な時間があります。 (今コンストラクタ呼び出しの階層
class A{
protected:
int _i;
public:
A(){i = 0;}
A(int i) : _i(i){}
virtual ~A(){}
virtual void print(){std::cout<<i<<std::endl;}
};
class B : virtual public A{
protected:
int _j;
public:
B() : A(){_j = 0;}
B(int i, int j) : A(i), _j(j){}
virtual ~B(){}
virtual void print(){std::cout<<i<<", "<<j<<std::endl;}
};
class C : virtual public B{
protected:
int _k;
public:
C() : B(){_k = 0;}
C(int i, int j, int k} : B(i,j), _k(k){}
virtual ~C(){}
virtual void print(){std::cout<<i<<", "<<j<<", "<<k<<std::endl;}
};
int main(){
C* myC = new C(1,2,3);
myC->print();
delete myC;
return 0;
}
、私はその後、今度はコンストラクタAを呼び出す必要があり、新たなC(1,2,3)B(1,2)のコンストラクタを呼び出すがしたい1:ここで私は何をすべきかです)を使用して、_i = 1、_j = 2、_k = 3を格納します。しかし、クラスCのインスタンスmyCを作成するとき、何らかの理由で私は理解できませんが、呼び出される最初のコンストラクタはAの標準コンストラクタ、つまりA :: A()です。これは明らかに、保護された変数_iに値0が割り当てられているため、間違った結果につながります。コンストラクターA(1)は決して呼び出されません。なぜこれはそうですか?私はこれを非常に直感的なものと見なします。目的の動作を達成するために、型階層内のすべてのコンストラクタを明示的に呼び出すことを避けるための方法がありますか?
ヘルプのためのThx!
種類の回答はThxです。だから、私はStroustrupに戻って、仮想継承の概念を再読するつもりだと思う。デフォルトでそれを使用することは賢明ではないと思われます;) – user1999920
多くの人々は、継承がデフォルトで仮想ではない理由を不思議に思っています。さて、あなた自身で答えを見つけました:) – Gorpik