有人可以解释下面的多重继承,为什么即使使用参数化构造函数构造车辆类,也不会调用d类的参数化构造函数。
#include<iostream>
using namespace std;
class d{
public:
d()
{
cout<<"in default constructor of d"<<endl;
}
d(int x)
{
cout<<"in parametrized constructor of d"<<endl;
}
void a()
{
cout<<"a function of d";
}
};
class Vehical:virtual public d
{
public:
Vehical(int x):d(x)
{
cout<<"In paramterized constructor of Vehical" <<endl;
}
void a()
{
cout <<"a function of Vehical class"<<endl;
}
Vehical()
{
cout<<"default constructor of Vehical"<<endl;
}
};
class now: virtual public d
{
public:
void a()
{
cout <<"a function of now "<<endl;
}
now()
{
cout<<"Default constructor of now" <<endl;
}
};
class car :public Vehical, public now
{
public:
car();
car(int y):Vehical(y)
{
};
//using d::a;
using Vehical::a;
};
int main()
{
car ob(1);
ob.a();
return 0;
}
输出:
in default constructor of d
In paramterized constructor of Vehical
Default constructor of now
期望:它应该已经调用了D的参数化构造函数,而不是默认值,因为我们通过传递参数来构造车辆,的确调用了D类的参数化构造函数。
如果我们再删除一个类别的虚拟,又遇到钻石问题?为什么会这样?
场景1): 如果从车辆类别中删除虚拟,我们将得到以下输出
in default constructor of d
in parametrized constructor of d
In paramterized constructor of Vehical
Default constructor of now
a function of Vehical class
在上面的输出中为什么也要先调用默认构造函数然后再调用d类的参数?为什么在输出中为什么先要先调用d的构造函数,然后又调用Vehicle和现在的类构造器。
期望:它应该先调用d的参数化构造函数,然后再调用Vehicle的参数化构造函数,然后再调用d的默认构造函数,然后调用现在的默认构造子
场景2) 现在我们现在从now类中删除virtual,并得到输出,其中调用d的默认构造函数而不是paramterize吗?
in default constructor of d
In paramterized constructor of Vehical
in default constructor of d
Default constructor of now
a function of Vehical class
期望:它应该在第一行调用D的参数化构造方法,而不是默认值。
答案 0 :(得分:0)
在可怕的死亡钻石中,存在两个问题:
1。基类的歧义-在引用此“祖父”类时,应选择该基类的基类。
2。显式调用基类构造函数时,使用哪个祖父类构造函数。想象以下示例:
class foo{
public:
foo() { }
foo(int x) { }
};
class bar : virtual public foo
{
public:
using foo::foo;
};
class baz: virtual public foo
{
public:
using foo::foo;
};
class clazz :public bar, public baz
{
public:
clazz(int i) : bar(i), baz(i+1){}
};
编译器应该选择foo
的哪个构造函数,因为只创建一个祖父?好吧,任何选择都意味着解决冲突的foo
构造函数调用之间的竞争(冲突意味着不同的参数)。 C ++中的语言设计选择是-不要尝试解决竞争,而要把初始化祖父类的责任放回程序员身上。这是有道理的,因为钻石继承是一个极端的情况,可能需要特殊的初始化方式。
您必须在孙类构造函数中显式调用d
构造函数:
#include<iostream>
using namespace std;
class d{
public:
d()
{
cout<<"in default constructor of d"<<endl;
}
d(int x)
{
cout<<"in parametrized constructor of d"<<endl;
}
void a()
{
cout<<"a function of d";
}
};
class Vehical:virtual public d
{
public:
Vehical(int x):d(x)
{
cout<<"In paramterized constructor of Vehical" <<endl;
}
void a()
{
cout <<"a function of Vehical class"<<endl;
}
Vehical()
{
cout<<"default constructor of Vehical"<<endl;
}
};
class now: virtual public d
{
public:
void a()
{
cout <<"a function of now "<<endl;
}
now()
{
cout<<"Default constructor of now" <<endl;
}
};
class car :public Vehical, public now
{
public:
car();
car(int y):Vehical(y), d(y)
{
};
//using d::a;
using Vehical::a;
};
int main()
{
car ob(1);
ob.a();
return 0;
}