我的問題涉及公共和私有繼承的組合作爲分離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'中使用它。 –