标题:[求助]虚继承的问题
只看楼主
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
得分:0 
以下是引用wfpb在2007-6-2 1:35:32的发言:
是啊,我是说明为什么会调用失败的原因,因为子类要在初始化列表中构造他所有的直接基类以及非直接虚基类。
而Usable_lock()这个非直接虚拟基类的构造函数是无参构造函数,可以省略,所以在class DD中就没有显示写出,但是其实是存在的,也即是说DD类的构造函数是这样的:
DD:Usable_lock(),Usable(){}

之前已经明白了......


Viva,espana!
2007-06-02 22:48
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
得分:0 
哦,不好意思,我累赘了!

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2007-06-03 15:15
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
得分:0 
以下是引用wfpb在2007-6-3 15:15:36的发言:
哦,不好意思,我累赘了!

没有啊,我只是以为你认为我问怎样才能使之编译通过


Viva,espana!
2007-06-03 16:40
kisscjy
Rank: 1
等 级:新手上路
帖 子:217
专家分:0
注 册:2007-4-9
得分:0 
学到东西了~~~谢谢~~~

原来虚继承会调转继承顺序滴~~~

每当我一晚写下70,80个程序时,你还真以为,这都是我一个人干的.....不过说真的,其实都是抄书的~~ ^@^
2007-06-03 21:41
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
得分:0 
以下是引用kisscjy在2007-6-3 21:41:32的发言:
学到东西了~~~谢谢~~~

原来虚继承会调转继承顺序滴~~~

你的签名真有趣


Viva,espana!
2007-06-04 09:46
zakker
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2007-6-4
得分:0 

class base //基类
class derive1 : public base
class derive2 : public base
class derive3 : public derive1,public derive2
===================================================
class base //基类
class derive1 : virtual public base
class derive2 : virtual public bass
class derive3 : public derive1,public derive2
=====================================================
我认为在非虚继承的时候 在构造derive3时,其父类调用顺序为derive1-base-derive2-base
构造函数顺序是 base-derive1-base-derive2
在虚继承的时候,在构造derive3时,其父类调用顺序为derive1-base-derive2
构造函数顺序是 base-derive1-derive2
并非你说的那样

2007-06-04 13:42
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
得分:0 

楼上的真是细心,是我没叙述清楚,我这里说的是一个父类访问顺序,并非构造函数执行的顺序。
比如非虚继承,还是那个例子,
在创建derived3时,顺序(访问顺序)是derived1-base-derived1-derived2-base-derived2;
红色部分为构造函数执行顺序。
而虚继承中:
在创建derived3时,顺序(访问顺序)是base-derived1-derived2.
同样红色部分为构造函数执行顺序。

这样就可以根据访问顺序,看到是谁在访问父类,所以解决最初那个问题。

由于那时写的匆忙,没有说明清楚。见谅了!谢谢指出。


Fight  to win  or  die...
2007-06-04 14:17
zakker
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2007-6-4
得分:0 

class Usable;
class Usable_lock
{ //这家伙把这个类的构造函数声明为私有并把Usable类声明为他的友元
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};

class Usable : public virtual Usable_lock //虚继承Usable_lock类
{ // ...
public:
Usable();
Usable(char*); // ...
};

class DD : public Usable
{ };
int main()
{
Usable a;
DD dd; //错误!因为 DD 不能访问 Usable_lock 的构造函数,也就创建不了 dd,防止了Usable被继承
return 0;
}
//这里的如果Usable不是虚继承基类的话DD dd;就不会错,虚继承决定了什么?!
===================================================================================
楼上的 我有2个问题请教:
1,请问下就楼主的题目而言,在创建DD dd的时候,DD Usable Usable_lock这3个类访问的顺序和构造的顺序是什么,
我看不出用了多次Usable_lock的构造函数来阻止 Usable的再继承,我觉得只用了一次;
2,楼主指出,如果不是虚继承的话 DD dd就是正确的,我试过确实是,请问下DD 并不是Usable_lock的友元,却为什么能访问Usable_lock的私有段,难道说 Usable和它基类的友元关系被继承下来了?
2007-06-06 00:31
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
得分:0 
回复:(zakker)class Usable;class Usable_lock { ...

你的两个问题确实就是一个问题,你不明白,DD类是怎么和Usable_lock类是怎样作用的。

首先,在非虚继承时,能通过编译。这时,在创建DD对象时,要创建其直接基类子对象,所以由DD类访问到Usable类,要创建usable类对象,要创建其直接基类Usavle_lock类的子对象,所以由Usable访问Usable_lock类,所以可以成功。

而在虚继承中,DD类会首先访问Usable_lock类,所以不成功。

#include <iostream>
using namespace std;
struct base{
base(){cout << "construct base\n";}
};

struct derived1 : /*virtual*/ base{
derived1(){cout << "construct derived1\n";}
};

struct derived2 : /*virtual*/ base{
derived2(){cout << "construct derived2\n";}
};

struct derived3 : derived1,derived2{
derived3(){cout << "construct derived3\n";}
};

int main(){
derived3 obj;
}

把注释部分加上和去掉的不同情况下,去单步调试下,帮助你理解。

Fight  to win  or  die...
2007-06-06 10:31
zkkpkk
Rank: 2
等 级:论坛游民
威 望:5
帖 子:489
专家分:28
注 册:2006-6-17
得分:0 
回复:(zakker)class Usable;class Usable_lock { ...
因为继承顺序的问题,所以DD通过他“父亲”调了“爷爷”的函数

Viva,espana!
2007-06-07 22:28



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-143735-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026385 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved