我的问题涉及公共和私有继承的组合作为分离C++类中的接口和实现的工具。在此模式中,接口基类声明了常用功能(class Base0
)。常见的实现是在一个从接口基础(class Impl0 : virtual public Base0
)虚拟派生的类中执行的。这个类包含任何常见的数据成员。扩展类分两步写入。首先,扩展接口由接口基地的虚拟继承来定义(class Base1 : virtual public Base0
)。其次,通过公开从Base1
(用于接口)和私人从Impl0
(用于实现)推导出扩展实现:class Impl1 : public virtual Base1, private Impl0
。我的问题如下:实现层次结构中的冗余私有成员数据复制
(1)如果扩展类中的函数定义的函数需要Impl0
中的公用数据,那么我必须在“Impl1”中复制那些数据吗?
(2)有什么办法可以避免这种复制?作为一个最基本的例子,考虑实现四个基本算术函数的类层次结构:add(),substr(),mult()和div()。基本版本MathOps
包含add()和subtr()函数。扩展版本MathOps_Extn
包含mult()和div()。上述技术提供了以下类层次结构。
#include<iostream>
using std::cout;
using std::endl;
class MathOps {
public:
virtual int add(int x) = 0;
virtual int subtr(int x) = 0;
};
class MathOps_Impl : public virtual MathOps {
private:
int m_y;
public:
MathOps_Impl(int y) : m_y(y) {
cout << "MathOps_Impl initialized with value: " << m_y << endl;
}
virtual int add(int x) { return x + m_y;}
virtual int subtr (int x) { return m_y - x;}
};
class MathOps_Extn : public virtual MathOps {
// Extends MathOps by adding mult() and div()
public:
virtual int mult(int x) = 0;
virtual int div(int x) = 0;
};
class MathOps_Extn_Impl : public virtual MathOps_Extn, private MathOps_Impl {
private:
int m_y; // Have to replicate member data m_y here.
public:
MathOps_Extn_Impl(int y) : MathOps_Impl(y), m_y(y) {
cout << "MathOps_Extn_Impl initialized with value: " << m_y << endl;
}
virtual int mult(int x) {
return x * m_y;
}
virtual int div(int x) {
int quotient = x == 0? 0 : m_y/x;
return quotient;
}
};
int main() {
MathOps_Extn* B = new MathOps_Extn_Impl(10);
cout << "add 20: " << B->add(20) << endl;
cout << "subtr 20: " << B->subtr(20) << endl;
cout << "mult 2: " << B->mult(2) << endl;
cout << "div 5: " << B->div(5) << endl;
注m_y
在MathOps_Extn_Impl
复制。有什么办法可以避免这种复制?
谁愿意适应算术运算成一个层次化的设计? –
再走一步,并拥有一个MathOps_Extn_base?或者把m_y放在MathOps中 – dchhetri
为什么不使用'protected'?但是如果你想用'private'修饰符继承,那么你必须重复它。把'm_y'放在接口中而不把'private'改成'protected'不会有太大的改变。 编辑:关于第一个问题,看看如何在C++中查找名称。如果你把'm_y'作为'Impl0'的保护对象,那么你应该可以在'Impl1'中使用它。 –