【问题标题】:Access Individual classes of a derived class, which is derived from two same base class访问派生类的各个类,派生类派生自两个相同的基类
【发布时间】:2013-04-02 13:07:23
【问题描述】:

我有一个名为Number基类OneTwo 类派生自 Number。 现在我定义了另一个类Three,我需要从多重继承中访问各个基类:


class Number{
  protected:
     int val;
  public:
    Number(){
        val=0;
    }
    void Add(Number n){//Receives another Number class instance and add the value
        val+=n.val;
    }
};

//class One derived from Number
class One:public Number{
  public:
     One(){
          cal=1;
     }
};

//class two derived from Number
class Two:public Number{
  public:
     Two(){
          val=2;
     }
};

class Three:public One,public Two{
  public:
     Three(){
          Two::Add(One);//--How can i pass instance of class One Here
     }
};

我试过 One::Number 和 Two::Number,但没有用。

【问题讨论】:

  • Add(One), One 不是您的类的实例,而是类型本身。您需要一个One 类型的变量。

标签: c++ multiple-inheritance diamond-problem


【解决方案1】:

有几个问题,首先val 是私有的,所以需要设置为protected。接下来你有一个diamond of death,所以你需要virtual public 对应OneTwo。您还尝试使用type 调用Add,但您需要每个类的instance

class Number{
protected:
     int val;
public:
    Number(){
        val=0;
    }
    void Add(Number& n){//Receives another Number class instance and add the value
        val+=n.val;
    }
};

//class One derived from Number
class One:virtual public Number{
public:
     One(){
          val=1;
    }
};

//class two derived from Number
class Two:virtual public Number{
public:
     Two(){
          val=2;
     }
};

class Three: public  One,  public  Two{
public:
     Three()
     {
           Two t1 ;
           Add(t1 );//--How can i pass instance of class Two Here
     }
};

可以说使用protected 数据是不好的,但它取决于on your case,但为了完整起见,保留val 一个private 数据成员并使用protected constructor 也是一种选择,那将看起来像这样:

class Number{
private:
     int val;
protected:
   Number( int n ) : val(n) {} 
public:
    Number(){
        val=0;
    }
    void Add(Number& n){//Receives another Number class instance and add the value
        val+=n.val;
    }
};

class One: virtual public Number{
public:
     One() : Number( 1 ) {

     }
};

class Two: virtual public Number{
public:
     Two() : Number(2) {
     }
};  

【讨论】:

  • 我不会为了将 val 设置在 ctor 中而保护它。您也可以创建一个受保护的 ctor Number::Number(int)
  • @DyP 我相信这取决于您的用例,但我修改了我的答案以涵盖这两个问题以及相关问题。
【解决方案2】:

这应该可行:

Two::Add(*(One*)this);

【讨论】:

  • 我最初发布了一个关于类型转换的提示作为评论,但是当你这样解决它时,你必须意识到你的类设计仍然存在严重的问题。
  • @DyP 在某些合法用例中,基类被继承了两次。这显然是一个简化的例子,无法判断真实的设计是否存在“严重问题”。
  • @Henrik 考虑到问题的程度,我认为这不太可能是预期的,至少应该注意其含义。
【解决方案3】:

您需要创建相应类型的对象。

class Three : public One, public Two
{
public:
     Three()
     {
          Add(One());
          Add(Two());
     }
};

但我不明白你为什么需要 MI。从 Number 继承就足够了。

【讨论】:

  • 我编辑了问题,我需要使用一个或两个的添加功能来添加另一个。
【解决方案4】:

问题不只是语法。但是你到底想做什么?

你可以。但是One 的实例在哪里声明?你必须先声明它。请记住 Two::Add(One); 不是声明而是调用语句。

你正在做的相当于让我们说

process_number(One);

其中进程号是一个函数。

【讨论】:

    猜你喜欢
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2020-02-11
    相关资源
    最近更新 更多