继承模型中问题

tweyseo 2008-03-19 11:50:39

class Cherry
{
protected:
virtual void sell(){cout << "Cherry" << endl;}
};

class BingCherry : public Cherry
{
};

class Test : public BingCherry
{
public:
void getInfo(){sell();}//这里的sell()方法到底是Cherry的还是BingCherry的呢?
};


class Cherry
{
protected:
virtual void sell() = 0;
};

class BingCherry : public Cherry
{
protected:
virtual void sell(){cout << "BingCherry" << endl;}
};

class Test : public BingCherry//这里没有去实现哪个虚函数,为什么还能创建对象呢?
{
public:
void getInfo(){sell();}
};
...全文
95 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 tweyseo 的回复:]
可是在多重继承的菱形结构中,当基类中定义了某个方法,而他下面的2个派生类没有重新写那个方法,然后在由这2个派生类派生出一个派生类,这里的最后一个派生类使用这个方法时就出现的二义性了,说明他是在他的2个基类中调用的那个方法.如果按照3楼的说法的话就不会产生二义性而直接去调用最开始的那个基类的方法了.
[/Quote]
现在是这个问题了
ryfdizuo 2008-03-19
  • 打赏
  • 举报
回复

Test类直接继承了BingCherry类,BingCherry里面的sell函数是唯一的,因为已经重写过了,
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
3楼的能解答下我的在4楼提出的疑问么?
okhere 2008-03-19
  • 打赏
  • 举报
回复
3楼正解
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
可是在多重继承的菱形结构中,当基类中定义了某个方法,而他下面的2个派生类没有重新写那个方法,然后在由这2个派生类派生出一个派生类,这里的最后一个派生类使用这个方法时就出现的二义性了,说明他是在他的2个基类中调用的那个方法.如果按照你的说法的话就不会产生二义性而直接去调用最开始的那个基类的方法了.
  • 打赏
  • 举报
回复
1因为BingCherry没有重新写一个,所以就是Cherry的
2是这样的,只要继承体系中有实现即可
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
1 为什么是Cherry的 sell呢?BingCherry也不是继承了Cherry的sell()方法?
2 难道说是是要虚基类下面的任意一个派生类实现了虚基类中的虚函数,那个派生类后面的派生类就都可以创建对象了么?
  • 打赏
  • 举报
回复
1 是Cherry的 sell
2 因为BingCherry实现了虚函数,所以就可以创建了
  • 打赏
  • 举报
回复
不是副本就对了。
因为BingCherry也是Cherry类型,所以拥有Cherry所拥有的一切。
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
那是不是我个人的理解错误啊?
我对继承的理解是在派生类中包含了基类中的非private的副本(包括方法和数据成员),
可是按你的意思来说好像是说派生类只是可以使用基类中的非private的方法和数据成员
并不是以副本的方式用拥有他们,所以当Test类要使用BingCherry的sell方法时候,还要
追溯到真正定义这个方法的Cherry类中去,对么?
  • 打赏
  • 举报
回复
是直接继承基类的,ABingCherry的sell和基类的相同
继承BingCherry也就拥有了BingCherry的sell,而BingCherry的sell和基类的相同。
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 paidfighting 的回复:]
引用 12 楼 tweyseo 的回复:
....你用的虚继承..在类B和类C中就根本就没有test()函数的实现被继承下来,就算被继承下来了编译器也不会去实现他们的,这里的D还是使用的A的test();
你把virtual去掉看看..编译器肯定会说:类似"reference to `test' is ambiguous"的错误.


。。。什么叫菱形结构?你不用虚基类做一个菱形结构我看看

虚基类(虚继承)就是用来解决你说的歧义问题的,你找出了“不用虚继承而会有歧义”的问…
[/Quote]
呃...我只是为了举出这个菱形的歧义问题只是为了证明"派生类是继承其直接基类(s)的方法"的说法的,呵呵.
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
可是我认为D是从B和C分别继承了1次test(),也就是说他是继承的他的直接基类(s)的方法,这个也就是我前面最开始的问题,所以我觉得是BingCherry的sell()
paidfighting 2008-03-19
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 tweyseo 的回复:]
....你用的虚继承..在类B和类C中就根本就没有test()函数的实现被继承下来,就算被继承下来了编译器也不会去实现他们的,这里的D还是使用的A的test();
你把virtual去掉看看..编译器肯定会说:类似"reference to `test' is ambiguous"的错误.
[/Quote]

。。。什么叫菱形结构?你不用虚基类做一个菱形结构我看看

虚基类(虚继承)就是用来解决你说的歧义问题的,你找出了“不用虚继承而会有歧义”的问题是对的

可这就是虚继承存在的意义啊!!!

没有虚继承哪来的菱形结构
  • 打赏
  • 举报
回复
没有啊

D从A 继承了2次所以函数就是俩份了。
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
对我就是这个意思,可是这样的话不就和
[Quote=引用 3 楼 akirya 的回复:]
1因为BingCherry没有重新写一个,所以就是Cherry的
2是这样的,只要继承体系中有实现即可
[/Quote]
的第一点矛盾了么?
[Quote=引用 4 楼 tweyseo 的回复:]
可是在多重继承的菱形结构中,当基类中定义了某个方法,而他下面的2个派生类没有重新写那个方法,然后在由这2个派生类派生出一个派生类,这里的最后一个派生类使用这个方法时就出现的二义性了,说明他是在他的2个直接基类中调用的那个方法.如果按照你的说法的话就不会产生二义性而直接去调用最开始的那个基类的方法了.
[/Quote]
  • 打赏
  • 举报
回复
非虚拟的话
你用B 或者C 的就可以正常调用。
如果你的D中调用这个函数就有冲突了,编译器不知道是调用从B 继承过来的,还是C继承过来的。

class A{
public:
A()
{
}
virtual ~A()
{
}
virtual void test()
{
cout <<"A test" <<endl;
}
};
class B:public A
{
};

class C:public A
{

};
class D:public B, public C
{

};

int main()
{
D d;
B* pb = &d;
C* pc = &d;
pb->test();
pc->test();
return 0;
}




tweyseo 2008-03-19
  • 打赏
  • 举报
回复
....你用的虚继承..在类B和类C中就根本就没有test()函数的实现被继承下来,就算被继承下来了编译器也不会去实现他们的,这里的D还是使用的A的test();
你把virtual去掉看看..编译器肯定会说:类似"reference to `test' is ambiguous"的错误.
paidfighting 2008-03-19
  • 打赏
  • 举报
回复

class A{
public:
A()
{
}
virtual ~A()
{
}
virtual void test()
{
cout <<"A test" <<endl;
}
};
class B:public virtual A
{
};

class C:public virtual A
{

};
class D:public B, public C
{
public:
void dosth()
{test();}
};


int _tmain(int argc, _TCHAR* argv[])
{

D d;
d.test();
d.dosth();
}


有什么问题?
tweyseo 2008-03-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 paidfighting 的回复:]
引用 4 楼 tweyseo 的回复:
可是在多重继承的菱形结构中,当基类中定义了某个方法,而他下面的2个派生类没有重新写那个方法,然后在由这2个派生类派生出一个派生类,这里的最后一个派生类使用这个方法时就出现的二义性了,说明他是在他的2个基类中调用的那个方法.如果按照你的说法的话就不会产生二义性而直接去调用最开始的那个基类的方法了.



你确定你的是菱形结构?


看这个


C/C++ code
class A{
public:

[/Quote]
你的test()是在D的对象中使用的,D类也从A类继承来了test()方法,所以没错,但是,你这样
class D:public B, public C
{
dosth(){test();}
};
这样才是说的菱形继承层次中的二义性
加载更多回复(1)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧