关于虚基类的初始化程序,请大家帮我分析执行结果,谢谢!

smart_boy1 2004-12-25 11:16:50
//class2.h
#include <iostream.h>

class base1
{
public:
base1()
{
cout <<"Base1 Class\n";
}
};

class base2
{
public:
base2()
{
cout <<"Base2 Class\n";
}
};

class level_1:public base2, virtual public base1
{
public:
level_1()
{
cout <<"Level_1 Class\n";
}
};

class level_2:virtual public base2, public base1
{
public:
level_2()
{
cout <<"Level_2 Class\n";
}
};

class toplevel: public level_1, virtual public level_2
{
public:
toplevel()
{
cout <<"Toplevel Class\n";
}

};


//main.cpp
#include <iostream.h>
#include "class2.h"

void main()
{
toplevel object;
}

我的执行结果是:
Base1 Class
Base2 Class
Base1 Class
Level_2 Class
Base2 Class
Level_1 Class
Toplevel Class

教材上不是说"虚基类的构造函数在非虚基类之前调用"嘛, 可为什么会先得到"Base1 Class"了? 还有,为什么会有两个"Base1 Class"了??
谢谢!!
...全文
211 点赞 收藏 17
写回复
17 条回复
smart_boy1 2005年01月12日
结贴声明:
1. 对playmud(猪头流氓)老兄佩服的五体投地,现在我"斗胆"帮您总结一下您说的规则(不到之处还请您批评)
(1)先构造虚基类,按照从左到右,从上到下的顺序构造;
(2)再构造非虚基类,也是按照从左到右,从上到下的顺序构造;
(3)当虚基类被构造以后,就不会再次被初始化(只要一个副本),但非虚基类需要重新构造.

2.请问一下playmud老兄, 您说"查了一下书",我想知道您是在哪本书上找到这些规则的, 因为我也是"查了一下书",大多数教材上都讲的是"三个原则", 按照这些原则我才有了楼顶的那些问题.
我找的资料是:清华大学出版社 <<面向对象的理论与C++实践>> 作者:王燕 p285~286
现在可以看出该书p256页上的分析是错的!
回复 点赞
dragoonj 2005年01月11日
我是这样理解的,不知道对不对

因为所有虚基类都是由most derived class 来构造的,而且只构造一次
所以构造level_2时不会构造base2,构造level_1时不会构造base1

先构造所有虚基类,共有3个,base1,base2,level_2
base1
输出 Base1 Class
base2
输出 Base2 Class
level_2
输出 Base1 Class
Level_2 Class

然后构造其他基类
只有level_1
输出 Base2 Class
Level_1 Class

最后是自己
Toplevel Class

不过不知道作者在这里用虚基类到底有什么意义
回复 点赞
beyondtkl 2005年01月11日
HOHO 我是来学习的!!
回复 点赞
playmud 2005年01月11日
昨天晚上回去查了一下书,发现是这样的:
虚基类按照从左到右,从上到下的顺序构造,虚基类构造完了以后,非虚基类按照从左到右,从上到下的顺序构造。象一个倒过来的二叉树。因此上面的分析果然雷同了。其实上面的分析加上下面的就OK了。
base2 base1 base2 base1
\ /虚 虚\ /
level_1 level_2
\ 虚/
\ /
toplevel

为了好看,我把上面的base多写了两个,实际上他也是没有公用一个虚基类的。

按照上面的规则,就是base1 base2 base1(为了构造虚基类level_2) level_2;
然后base2 level_1 toplevel.
好了我们验证一下是否正确呢。
我们把class toplevel: public level_1, virtual public level_2改成
class toplevel: virtual public level_2,public level_1
按照上面的分析:
base2 base1 base2 base1
虚\ / \ /虚
level_2 level_1
\虚 /
\ /
toplevel
应该是base2 base1 level_2 base1,好了虚基类构造完毕。
然后是base2 level_1 toplevel 然后验证一下,没问题。
好累啊!
回复 点赞
playmud 2005年01月11日
实际上这么分析是错的。
回复 点赞
playmud 2005年01月11日
教材上不是说"虚基类的构造函数在非虚基类之前调用"嘛, 可为什么会先得到"Base1 Class"了?

你这个也不是虚基类啊,只不过你后面有虚拟继承。
书上还有说先构造基类吧?
好,那么往下看:
既然有虚继承,那么就需要先构造虚拟继承的基类,
Toplevel class往上的虚基类一共有三个:base1,base2,level_2,那么开始构造
base1 (1)
base2 (2)
然后开始构造level_2,构造他的时候发现他有一个虚基类已经构造ok了,那么只需要构造另外
一个不是虚拟继承的就行了,于是输出:
base1 (3)
然后是他自己
level_2; (4)
现在第一步工作ok了,toplevel开始按照他的直接上级构造了,从左到右。
应该构造level_1了,level_1的虚拟基类base1已经ok了,所以不用构造了,于是来,整另外一个,所以你又看到了:
base2(5)
然后构造自己
level_1(6)
好了,改搞得都搞了,开始搞自己了
top_level (7)

以上纯属YY,如有雷同纯属巧合。
回复 点赞
oyljerry 2005年01月10日
虚基类,我理解是用来解决菱形结构得二义性得
回复 点赞
smart_boy1 2005年01月10日
今天老师在课堂上讨论了整整一节课,可是还是没有给出个圆满的解答,自己在顶一下,请csdn的高人给个合理的解释。
回复 点赞
liem 2004年12月29日
class level_2:virtual public base2, public base1
说明base1不是leval_2的虚基类,因此在构造lwvwl_2时,也要构造一次base1
回复 点赞
smart_boy1 2004年12月29日
自己顶一下!
回复 点赞
sankt 2004年12月26日
路过
不过不清楚
关注
回复 点赞
believe_me 2004年12月26日
虚基类是为了避免多继承中直接基类有公共基类而出现重复继承的情况
A
/ \
B C
\ /
D
为了避免D中出现重复的A的成员,B,C均从A虚继承.
class A{ // ... };
class B:virtual public A{ //... };
class C:virtual public A{ //... }; //注意B和C从A继承时都有virtual
class D:public B,public C{ //... };

楼主你的程序根本没有构成虚基类...
这个是改后的,输出正确,先调用虚基类的构造函数,可用debug查看~~
#include <iostream.h>

class base1
{
public:
base1()
{
cout <<"Base1 Class\n";
}
};

class base2
{
public:
base2()
{
cout <<"Base2 Class\n";
}
};

class level_1:virtual public base2, virtual public base1
//class level_1:public base2, virtual public base1
{
public:
level_1()
{
cout <<"Level_1 Class\n";
}
};

//class level_2:virtual public base2, public base1
class level_2:virtual public base2, virtual public base1
{
public:
level_2()
{
cout <<"Level_2 Class\n";
}
};

class toplevel: public level_1,public level_2
//class toplevel: public level_1, virtual public level_2
{
public:
toplevel()
{
cout <<"Toplevel Class\n";
}

};

回复 点赞
zhengwei1984222 2004年12月26日
唉,这玩意平时用得少
只有gz了
回复 点赞
蒋晟 2004年12月26日
你不重载的话虚不虚没什么区别。像你这样写的话Toplevel Class只有一次把base类作为虚基类。
回复 点赞
oyljerry 2004年12月26日
试了一下,如楼主输出
回复 点赞
oyljerry 2004年12月26日
base1只继承了一次
回复 点赞
xuzheng318 2004年12月26日
就不用虚类了呗
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告