首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止C++中的多重继承

防止C++中的多重继承
EN

Stack Overflow用户
提问于 2013-12-19 08:24:41
回答 5查看 2.9K关注 0票数 16

最近,我参加了一次C++技术面试:在那次面试官问我一个我无法回答的问题时,我甚至在网上和一些论坛上尝试过,但是无法得到答案,请看下面的代码片段:

代码语言:javascript
复制
using namespace std;

class Base1
{
    public:
    Base1() 
    {
        cout << "Base1 constructor..." << endl;
    }

    ~Base1() 
    {
        cout << "Base1 Destructor..." << endl;
    }
};  

class Base2
{
public:
    Base2() 
    {
        cout << "Base2 constructor..." << endl;
    }

    ~Base2() 
    {
      cout << "Base2 Destructor..." << endl;  
    }
};

class Derived : public Base1, public Base2 
{
public:
  Derived()
  {
      cout << "Derived constructor...."  << endl;
  }
  ~Derived()
  {
      cout << "Derived Destructor..." << endl;
   }
};


int main()
{
   cout << "Hello World" << endl; 
   Base1 b1; Base2 b2;
   Derived d1;

   return 0;
}

Description:有两个基类名为Base1和Base2,另一个派生类名为派生。派生是从Base1和Base2继承的多个。

问题:我希望派生只能从一个类继承,而不是从两个类继承。如果开发人员试图从这两个类继承:那么错误应该生成:让我总结一下:

  • 1:派生的类: public Base1 // Ok.-->无错误
  • 2:派生的类: public Base2 // Ok.-->无错误
  • exception 3:派生的类:公共Base1、公共Base2 //错误或异常等。无法继承。

备注:你能回答这个问题吗?我真的不确定这是否可行。还有一件事:这不是钻石问题。

谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-12-19 09:45:22

在两个具有不同返回类型的基中声明一个纯虚函数:

代码语言:javascript
复制
class B1 {
   virtual void a() = 0;
};

class B2 {
   virtual int a() = 0; // note the different return type
};

这两者都不可能继承。

代码语言:javascript
复制
class D : public B1, public B2 {
public:
    // virtual void a() {} // can't implement void a() when int a() is declared and vice versa
    virtual int  a() {}
};

int main(void) {
    D d; // produces C2555 error
    return 0;
}

产生此错误:

  • 错误C2555:'D::a':重写虚拟函数返回类型不同,与'B1::a‘不存在协变量
  • 见“B1::a”声明
票数 29
EN

Stack Overflow用户

发布于 2013-12-19 09:55:17

您可以使用C++11来完成这个任务,请看:

代码语言:javascript
复制
#include <type_traits>
struct Base1 {}; 
struct Base2 {}; 

struct Derived 
   : public Base1
  , public Base2
{ 
  Derived() 
  { 
     static_assert( !(std::is_base_of< Base1, Derived >::value && std::is_base_of< Base2, Derived >:: value), "You cannot inherit from both Base1 and Base2" ); 
  } 
}; 



int main() { Derived d; return 0; }

只有从Base1或Base2继承时,它才能工作和编译。如果您试图从两者继承,它不会编译。如果您想要运行时错误,而不是编译时错误,甚至可以使用相同的方法来检查。试着玩这个片段。

票数 4
EN

Stack Overflow用户

发布于 2013-12-19 10:27:01

运行时检查:

代码语言:javascript
复制
#include <iostream>
#include <stdexcept>
#include <typeinfo>

class B1 {
    protected:
    template <typename D>
    B1(D* d) {
        // The paranoid 'is_same' is preventing the cast (B1*)this in the derived constructor.
        if((void*)this != (void*)d || std::is_same< B1, D >::value)
            throw std::logic_error("Multiple Inheritance [1]");
    }

    int data;
};

class B2 {
    protected:
    template <typename D>
    B2(D* d) {
        // The paranoid 'is_same' is preventing the cast (B2*)this in the derived constructor.
        if((void*)this != (void*)d || std::is_same< B2, D >::value)
            throw std::logic_error("Multiple Inheritance [2]");
    }

    int data;
};


struct D : public B1, public B2 {
    D()
    :   B1(this), B2(this)
    {}
};

int main() {
    D d;
}

注意:如果类为空,则此操作不起作用。不如@egur这个好主意好。不过,它的好处是不引入虚拟函数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20676637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档