可能性混合复合图案和好奇地重复模板模式 [英] Possibility to mix composite pattern and curiously recurring template pattern

查看:114
本文介绍了可能性混合复合图案和好奇地重复模板模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  class CObject {
private:

CObject * m_pParent;
CObjectContainer * m_pChildren;

void private_foo(){
this-> foo();
//为容器中的每个子元素调用private_foo。
m_pChildren-> foo();
}

public:
virtual void foo(){
//基类类为空的
}

virtual CObject * duplicate(){
//做重复的代码
return new CObject(* this);
}

virtual CObject * detach(){
//从当前树中删除此对象(及其子对象)
//。
m_pParent-> RemoveChild(this);
m_pParent = nullptr;
return this;
}
}

class CSpecificObject:public CObject {
public:
virtual void foo(){
// class
}

virtual CSpecificObject * duplicate(){
//重载,但是代码只调用diferent构造函数
return new CSpecificObject(* this);
}

virtual CSpecificObject * detach(){
//注意代码是否相同。
m_pParent-> RemoveChild(this);
m_pParent = nullptr;
return this;不幸的是,继承的类的数量会迅速增加,而重复的数量将会增加,所以你可能会遇到这样的问题:
}
}


$ b <代码(在给定的例子中只有detach()方法)给我一个头痛。



有一种方法来干净地实现detach同样的对象,它被称为?



我在想CRTP,但我不能想办法保持动态多态性与编译时多态性:

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

//不能再使用CObject *指针数组。


解决方案

您可以添加一个抽象级别:

  class CObjectBase 
{
public:
//其他方法...
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); //在这里需要转换(CRTP固有的)
}
std :: vector< CObjectBase *>儿童; // Array possible now
// ...
};

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

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

I have a composite pattern implementation, used for GUI components:

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;
  }
}

Unfortunately the number of inherited classes increases rapidly and the duplicate code (in given example only the detach() method) is giving me a headache.

Is there a way to cleanly implement detach() methods, keeping the return type the same as the object, on which it is called?

I was thinking about CRTP, but I can not think of a way to keep the dynamic polymorphism along with compile time polymorphism:

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.

解决方案

You can add one level of abstraction:

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>
{
    // ...
};

In natural language: an interface for all objects (CObjectBase) have a partial implementation for its descendants (CObject<Child>), which just have to inherit this partial implementation, decreasing the amount of replicated code.

这篇关于可能性混合复合图案和好奇地重复模板模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆