我的问题涉及公共和私有继承的组合,作为在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
的复制。有没有办法避免这种复制?
答案 0 :(得分:1)
请注意在MathOps_Extn_Impl中复制m_y。有什么办法吗? 避免这种复制?
是。授予MathOps_Impl::m_y
protected
访问权限,而不是private
。
您明确询问为什么派生类无法访问私有数据。这是设计的。
答案 1 :(得分:0)
您可以通过公共实现类中受保护的成员函数,在不破坏封装的情况下访问公共数据。
无条件的例子如下:)
#include <cstdio>
class Math
{
public:
virtual ~Math() {}
virtual int add(int b) const = 0;
};
class MoreMath : public virtual Math
{
public:
virtual ~MoreMath() {}
virtual int subtract(int b) const = 0;
};
class MathImpl : public virtual Math
{
private:
int m_a;
public:
MathImpl(int a) : m_a(a) {}
virtual ~MathImpl() {}
int add(int b) const { return m_a + b; }
protected:
int value() const { return m_a; }
};
class MoreMathImpl : public virtual MoreMath, private MathImpl
{
public:
MoreMathImpl(int a) : MathImpl(a) {}
int subtract(int b) const { return value() - b; }
};
int main()
{
MoreMath* one = new MoreMathImpl(1);
printf("1 + 2 = %d\n", one->add(2));
printf("1 - 2 = %d\n", one->subtract(2));
delete one;
return 0;
}