c ++如何用组合扩展一个类?

Posted

技术标签:

【中文标题】c ++如何用组合扩展一个类?【英文标题】:c++ How to extend a class with composition? 【发布时间】:2014-03-18 04:36:20 【问题描述】:

我最近遇到了以下问题。我有一个 Base 类,它有一个 Base_encapsulated_class。

class Base_class

public:
    Base_class(int int_value, short short_value) :
      m_encapsulated_class(int_value, short_value)
    ;

    ~Base_class(void);

    Base_encapsulated_class  m_encapsulated_class;
;

class Base_encapsulated_class

public:
    Base_encapsulated_class(int int_value, short short_value)
        : m_int(int_value),
        m_short(short_value)
    ;

    ~Base_encapsulated_class(void);

private:
    int m_int;
    short m_short;
;

现在我想同时扩展Base_classBase_encapsulated_class 来实现:

class Derived_class : public Base_class

public:
    Derived_class(int int_value, short short_value, bool boolean_value) :
      Base_class(int_value, short_value)
    ;

    ~Derived_class(void)
    ;

    Derived_encapsulated_class m_encapsulated_class;

;

class Derived_encapsulated_class : public Base_encapsulated_class

public:
    Derived_encapsulated_class(int int_value, short short_value, bool boolean_value) :
      Base_encapsulated_class(int_value, short_value),
          m_bool(boolean_value)
    
    

    ~Derived_encapsulated_class(void)
    
    

private:
    bool m_bool;
;

这种方法在派生类对象中为我提供了两个m_encapsulated_class 实例,这在 c++ 中显然是合法的(我有点惊讶)。

但这不是我想要的。我希望派生类中有一个 m_encapsulated_class 成员。那么是否可以在基类中扩展复合成员呢?

【问题讨论】:

C++ 中不能有“虚拟变量”——只有虚拟函数。 那么您如何实现这些目标呢?我猜想通过 ctor 传递子组件并将其排序为指针或引用? 我不是 OO 设计模式方面的专家,但这里有一些想法。 Base 可以有一个指向 Base_encapsulated_class 的智能指针,并且 Derived 必须在构造函数调用中向 Base 发送一个标志,以告诉它要构造哪种对象。不过,您可能会遇到隐私和封装问题,因为 Base 和 Derived 看不到 Base_encapsulated 等的非公共成员。或者,template<typename T = Base_encapsulated_class> class Base ... T m_encapsulated_class; ...; 然后在 Derived 中,Derived(): Base<Derived_encapsulated_class>() 【参考方案1】:

您可以使用虚拟 getter 来强制成员继承:

class Base_class

public:
    Base_class(int int_value, short short_value) :
      m_encapsulated_class(int_value, short_value)
    ;

protected:
    virtual Base_encapsulated_class Get_encapsulated_class() /* = 0 if you want to enforce encapsulated derivation */
    
       return m_encapsulated_class;
    


private:
    Base_encapsulated_class  m_encapsulated_class;
;


class Derived_class : public Base_class

public:
    Derived_class(int int_value, short short_value, bool boolean_value) :
      Base_class(int_value, short_value)
    ;

    ~Derived_class(void)
    ;

protected:
    virtual Base_encapsulated_class Get_encapsulated_class() 
    
       return m_derived_encapsulated_class;
    

private:

    Derived_encapsulated_class m_derived_encapsulated_class;

;

【讨论】:

你真的应该返回指向Base_encapsulated_class的指针或引用以避免切片 你是对的。我没有使用它来避免混淆,但是如果 OP 想在 xxx_encapsulated_class 对象上使用有状态的方法,则必须有某种引用。 将封装类设为私有的加分项 - 仅此一项就会增加可维护性,因为很明显派生类看不到私有变量。

以上是关于c ++如何用组合扩展一个类?的主要内容,如果未能解决你的问题,请参考以下文章

如何用C语言编写PHP扩展的详解

如何用C语言编写PHP扩展的详解

如何用Java程序来编写一个异常?

如何用C语言编写一个窗体应用程序?

如何用 C 预处理器编写一个 while 循环?

组合继承多态