繁体   English   中英

如何合并在C ++中共享相同基类的两个类?

[英]how to combine two classes that share the same base class in C++?

我给出以下示例来说明我的问题:

class Base
{
 public:
   virtual void do()=0;
}

class A: public Base
{
public:
  void do();
};

class B: public Base
{
 public:
  void do();
}

class AB: public Base
{ 
 public:
 void do()
  {
     a_.do();
     // if not succeed
     {
        b_.do();
     }
    }
private:
 A a_;
 B b_;

}

从上面的代码中,我们可以看到A, BAB类来自同一基类。 但是,类AB需要同时调用类A和类B 这是我的问题: AB类的潜在问题是什么? 还有其他选择吗?

一种替代方法可能是:

class Base
{
 public:
   virtual void do()=0;
}

class A: public Base
{
public:
  void do();
};

class B: public Base
{
 public:
  void do();
}

class AB: public A
{ 
 public:
 void do()
  {
     A::do();
     // if not succeed
     {
        b_.do();
     }
    }
private:

 B b_;

}

AB类的潜在问题是什么?

我不知道您的设计必然会引起任何众所周知的问题。 您应该问自己“为什么会出问题?”。

还有其他选择吗?

有很多选择。 例如, AB都不包含任何状态,因此您也可以停止使用支持自由函数的类,并用函数指针替换动态绑定。

为了能够比较不同的替代方案,您应该首先确定要解决的问题。

我不知道你真正想要实现什么。 但是,如果您所有的类仅应具有来自Base的实例数据的一个副本,则需要一个虚拟的Base类。

关于AB的第一个示例的问题是,您有三个! 乘以Base类的数据。 一个是继承自Base,一个是成员B的一部分,成员B本身又是从Base继承而来的,又是成员A的成员。那是您的意图吗?

我为您简要介绍了以下内容,以了解如何在所有类实例中使用Base的一个精确副本。 也许那就是您想要得到的?

我向Base添加了一些数据,以查看使用虚拟基类时构造如何工作。 重要的是,不要从直接继承的类的构造函数中调用基类的构造函数! 您需要直接从最外层构造函数调用该构造函数,如AB类构造函数所示!

备注:仅在没有其他适合设计的情况下才应使用虚拟基类。 通常需要这种解决方案会显示出设计问题。 但是像在编程中一如既往:如果这完全满足您的需求,那么从技术上讲绝对可以。

class Base
{   
    private:
        std::string text;

    public:
        Base( const std::string& str ): text(str) {}
        virtual void Do() { std::cout << text << std::endl; }
};  

class A: virtual public Base
{   
    public:
        A():Base("Default from A") {}
        void FuncA() { std::cout << "FuncA" << std::endl; }
       void Do() { std::cout << "Via A" << std::endl; Base::Do();}
};  

class B: virtual public Base
{   
    public:
        B(): Base ("Default from B") {}
        void FuncB() { std::cout << "FuncB" << std::endl; }
};  

class AB: public A,B 
{   
    public:
        //Important to know that init of Base MUST be done from here and not from A nor B !!
        AB( const std::string &s): Base(s) {}
        void Do() { std::cout << "Via AB" << std::endl; Base::Do(); A::Do(); B::Do();}
};  

int main()
{   
    A a;
    a.Do();
    std::cout << "####" << std::endl;

    B b;
    b.Do();
    std::cout << "####" << std::endl;

    AB ab("Hallo"); 
    ab.Do();
    std::cout << "####" << std::endl;
}   

您应该从A和B继承,而不是从Base继承,因为A和B已经这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM