了解虚拟基类和构造函数调用
我对虚拟基类的工作原理有点困惑。特别是,我想知道如何调用基类的构造函数。我写了一个例子来理解它:
#include <cstdio>
#include <string>
using std::string;
struct A{
string s;
A() {}
A(string t): s(t) {}
};
struct B: virtual public A{
B(): A("B"){}
};
struct C: virtual public A {};
struct D: public B, public C {};
struct E: public C, public B {};
struct F: public B {};
int main(){
D d;
printf("\"%s\"\n",d.s.c_str());
E e;
printf("\"%s\"\n",e.s.c_str());
F f;
printf("\"%s\"\n",f.s.c_str());
B b;
printf("\"%s\"\n",b.s.c_str());
}
哪些输出
""
""
""
"B"
我不确定在前两种情况下会发生什么,但对于第三种情况,至少我期望输出为“B”。所以现在我很困惑。理解 A 的构造函数如何被调用的规则是什么?
I'm a bit confused about how virtual base classes work. In particular, I was wondering how the constructor of the base class gets called. I wrote an example to understand it:
#include <cstdio>
#include <string>
using std::string;
struct A{
string s;
A() {}
A(string t): s(t) {}
};
struct B: virtual public A{
B(): A("B"){}
};
struct C: virtual public A {};
struct D: public B, public C {};
struct E: public C, public B {};
struct F: public B {};
int main(){
D d;
printf("\"%s\"\n",d.s.c_str());
E e;
printf("\"%s\"\n",e.s.c_str());
F f;
printf("\"%s\"\n",f.s.c_str());
B b;
printf("\"%s\"\n",b.s.c_str());
}
Which outputs
""
""
""
"B"
I wasn't sure what would happen in the first two cases, but for the third one at least I was expecting the output to be "B". So now I'm just confused. What are the rules for understanding how the constructor of A gets called?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
始终只有一个构造函数调用,并且始终是您实例化的实际具体类。 您有责任为每个派生类赋予一个构造函数,该构造函数在必要时调用基类的构造函数,就像您在
B
的构造函数中所做的那样。更新:很抱歉错过了您的要点!感谢伊尔贾恩。
但是,您的
B
实际上继承了A
。根据标准(FIDS 中的 10.1.4),“对于指定为虚拟的每个不同基类,最派生的对象应包含该类型的单个基类子对象”。在您的情况下,这意味着在构造基类时,您的类F
立即调用A
的默认构造函数,而不是B
的默认构造函数。There is always just one constructor call, and always of the actual, concrete class that you instantiate. It is your responsibility to endow each derived class with a constructor which calls the base classes' constructors if and as necessary, as you did in
B
's constructor.Update: Sorry for missing your main point! Thanks to ildjarn.
However, your
B
inherits virtually fromA
. According to the standard (10.1.4 in the FIDS), "for each distinct baseclass that is specified virtual, the most derived object shall contain a single base class subobject of that type". In your case this means that when constructing the base, your classF
immediately callsA
's default constructor, notB
's.虚拟基类总是由最派生的类构造。
Virtual base classes are always constructed by the most derived class.