当前位置:  开发笔记 > 编程语言 > 正文

多重继承

如何解决《多重继承》经验,为你挑选了1个好方法。



1> Suma..:

继承两次

对于双重继承,你有一个歧义 - 编译器无法知道你想要使用哪两个A基.如果你想拥有两个A基数(有时你可能想要这样做),你可以通过转换为B或C来选择它们.这里默认转换的最合适的是static_cast(作为最弱的),但它不是真的需要(它仍然比你的情况需要更强),因为你没有强制转换为派生类型.自定义safe_cast模板应该完成这项工作:

/// cast using implicit conversions only
template 
inline To safe_cast( const From &from ) {return from;}

main()
{

  D obj;
  foo(safe_cast(&obj)); //error. How do i call with D's B part.

}

编译时间类型 - 使用模板

此外,在虚拟继承的情况下,为什么偏移信息需要存储在vtable中.这可以在编译时自己确定.在上面的例子中,如果我们用D的对象传递foo,在编译时我们只能计算D的A部分的偏移量.

这是一种误解.现在编写的foo函数没有关于ptr类型的编译类型信息,除非它是A*,即使你传递B*或C*.如果你希望foo能够根据传递编译时间的类型进行操作,你需要使用模板:

template 
int foo(TypeDerivedFromA *ptr)
{
  ptr->eat();
}

虚拟继承

您的问题提到了虚拟继承.如果要使用虚拟继承,则需要指定:

class B: public virtual A ...

class C: public virtual A ...

有了这个代码就会编译,但是使用这个解决方案,你无法在B :: A或C :: A(只有一个A)之间进行选择,因此这可能不是你的意思.

虚拟功能

此外,您的问题似乎混淆了两个不同的概念,虚拟继承(这意味着在两个中间基类之间共享一个基类)和虚函数(这意味着允许通过基类指针调用派生类函数).如果你想使用A指针调用B :: eat,你可以使用虚函数执行此操作而不使用虚拟继承(实际上虚拟继承会阻止你这样做,如上所述):

class A
{
   int a;
   int b;

   public:
   virtual void eat()
   {
      cout<<"A::eat()"<

如果您不接受虚函数,则此编译时机制是模板,如上所述.

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有