0

我的问题涉及公共继承和私有继承的组合作为在 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注意in的复制MathOps_Extn_Impl。有没有办法避免这种复制?

4

2 回答 2

1

请注意 MathOps_Extn_Impl 中 m_y 的复制。有没有办法避免这种复制?

是的。授予MathOps_Impl::m_y protected访问权限而不是private.

您明确询问为什么派生类无法访问私有数据。这是设计使然。

于 2013-01-17T22:41:22.833 回答
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;
}
于 2013-01-18T02:08:11.193 回答