设计模式-如何在C++中组合共享同一基类的两个类
design patterns - 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, B
和AB
来自同一个基类。然而,类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_;
}
我不知道你真正想要实现什么。但是,如果所有类都应该只有一个来自Base的实例数据副本,则需要一个虚拟基类。
AB的第一个例子的问题是,你有三个!乘以Base类的数据。一个来自inherit 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;
}
AB类的潜在问题是什么?
我不知道你的设计会产生什么众所周知的问题。你应该问问自己"为什么会出现问题?"。
还有其他选择吗?
有很多选择。例如,A
和B
都不包含任何状态,所以您也可以停止使用类来支持自由函数,并用函数指针替换动态绑定。
为了能够比较不同的替代方案,你应该首先决定你试图解决什么问题。
您应该从A和B继承,而不是从Base继承,因为A和B已经继承了。
相关文章:
- 如何允许模板参数中的类类型,仅当它有两个基类时
- 两个抽象类,派生自同一个基类.如何访问从一个抽象类到另一个抽象类的指针
- 从两个不同类继承的非虚拟基类的访问成员
- 具有相同纯虚拟功能的两个基类
- 为什么当我有两个函数时编译器没有显示错误,一个将采用基类,一个将派生类作为参数
- 模板化成员函数能否实现两个基类的虚函数?
- 来自两个相同基类的 C++ 派生类
- C++ 类两个动态属性
- 如何在具有相同基类的两个不同类中获取向量
- 实现两个名称相同但由于多个抽象基类而不同的非协变返回类型的函数
- 有没有办法区分来自两个模板化基类的这些函数调用
- 同一基类的两个派生对象如何通信
- 如何知道两个对象是否派生自同一基类
- 如何通过定义派生类的构造函数来实例化两个基类的私有数据成员
- C++在派生类和基类中使用两个同名变量
- 当继承基模板类并将两个类文件放在单独的头文件中时,为什么会出现重定义错误
- 如何在两个不同对象的基类中使用模板化类
- 模板类两个重载函数
- 获取从基类指针到具有不同类型的两个派生成员变量的访问权
- 当基类具有两个或多个模板参数时,C++11 别名基模板类变量在模板派生类中不起作用