c++ - 混合复合模式和奇怪的重复模板模式的可能性

标签 c++ templates design-patterns composite crtp

我有一个复合模式实现,用于 GUI 组件:

class CObject {
private:

  CObject * m_pParent;  
  CObjectContainer * m_pChildren;

  void private_foo() {
    this->foo();
    //Calls private_foo for each child in container.
    m_pChildren->foo();
  }

public:
  virtual void foo() {
    //empty for base class
  }

  virtual CObject * duplicate() {
    //Do duplication code
    return new CObject(*this);
  }

  virtual CObject * detach() {
    //Remove this object (along with it's children)
    //from current tree.
    m_pParent->RemoveChild(this);
    m_pParent = nullptr;
    return this;
  }
}

class CSpecificObject : public CObject {
public:
  virtual void foo() {
    //Specific code for this class
  }

  virtual CSpecificObject * duplicate() {
    //Overload, but the code only calls diferent constructor
    return new CSpecificObject(*this);
  }

  virtual CSpecificObject * detach() {
    //Note the code is identical.
    m_pParent->RemoveChild(this);
    m_pParent = nullptr;
    return this;
  }
}

不幸的是,继承类的数量迅速增加,重复的代码(在给定的示例中只有 detach() 方法)让我很头疼。

有没有一种方法可以干净地实现 detach() 方法,使返回类型与调用它的对象相同?

我在考虑 CRTP,但我想不出一种方法来保持动态多态性和编译时多态性:

template <Child>
class CObject {
private:
  ...
  Child * detach() {
    m_pParent->RemoveChild(this);
    m_pParent = nullptr;
    return static_cast<Child*>(this);
  }
  ...
}

//Array of CObject* pointers is no longer possible.

最佳答案

您可以添加一层抽象:

class CObjectBase
{
    public:
        // Other methods...
        virtual CObjectBase* detach() = 0;
        virtual CObjectBase* duplicate() const = 0;
};

template <typename Child>
class CObject : public CObjectBase
{
    public:
        // ...
        Child* duplicate() const
        {
            return new Child(*static_cast<Child*>(this));
        }

        Child* detach()
        {
            m_pParent->RemoveChild(this);
            m_pParent = nullptr;
            return static_cast<Child*>(this); // Cast needed here (inherent to CRTP)
        }
        std::vector<CObjectBase*> children; // Array possible now
        // ...
};

class MyObject : public CObject<MyObject>
{
    // ...
};

在自然语言中:所有对象的接口(interface) (CObjectBase) 都有其后代 (CObject<Child>) 的部分实现,它只需要继承这个部分实现,减少了复制代码的数量。

关于c++ - 混合复合模式和奇怪的重复模板模式的可能性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13867901/

相关文章:

头文件中的 C++ 静态原型(prototype)声明

C++:比较运算符 > 和字符串文字的意外结果

c++ - 用模板复制构造函数替换默认复制构造函数

c++ - 如何在没有基础模板参数的情况下将模板模板参数传递给模板类?

c++ - 为什么 std::function 不能与函数模板一起使用?

javascript - 如何处理这些异步函数(设计模式?)

c++ - C++函数中非常奇怪的优先级/优先级

c++ - 什么是在 C++ 中重载构造函数的正确而优雅的方法

c# - 工厂模式 : Restrict object construction to factory

具有最终用户提供的字段的类的 Java 构造函数