这是mixins构造函数问题的有效解决方法吗?

时间:2011-06-22 13:25:19

标签: c++ constructor decorator mixins

据我所知,mixins存在一个问题,如果你想使用非arg构造函数以外的东西,你使用mixin的对象要么必须有一个共同的构造函数签名,要么你必须使用初始化程序要使用mixin的类中的方法。

这似乎是一种解决方法,但我不确定是否存在失败的情况。它使mixin更像装饰器,但它不需要装饰器继承的通用接口。我想另一个问题是语法可能变得笨重?

只是想知道这是否有任何可怕的危险。我也想知道,作为一个不那么聪明的程序员,我是否误解了mixin这个问题。

编辑:这似乎是一个更好的表述。

class Base
{
protected:
    std::string name;
public:
    Base()
    {
        name = "no arg constructor";
    }
    Base(std::string n)
    {
        name = n;
    }

    virtual void doSomething()
    {
        cout << name << "\n";
    }
};

class Derived : public Base
{
private:
    int x;
public:

    Derived(std::string n, int i) : Base(n)
    {
        x = i;
    }

    void doSomething()
    {
        cout << "x = " << x << "\t";
        Base::doSomething();
    }
};

template <class T>
class Decorator : public T
{
public:
    Decorator(const T& initializer) : T(initializer)
    {
        //*static_cast< T* >(this) = *initializer;
        //delete initializer;
    }
};

void method(Base& b)
{
    b.doSomething();
}

int main()
{
    Base b;
    Decorator<Base> d1(b);
    Decorator<Base> d2(Base("decorated"));
    Decorator<Derived> d3(Derived("derived", 777));

    method(d1);
    method(d2);
    method(d3);

    return 0;
}

没有arg构造函数

装饰

x = 777派生

2 个答案:

答案 0 :(得分:3)

这就是为什么C ++ 0x包含能够安全地转发任意数量的元素的原因:

template <typename T>
struct Decorator: T
{
  template <typename... Args>
  Decorator(Args&&... args): T(args...) {}
};

干净地转发论据。请查看ideone

答案 1 :(得分:3)

  1. 如果在施工期间抛出异常,您就会泄漏内存,
  2. 基类必须首先构造一个默认构造函数,然后再分配。
  3. 更好:

    Decorator(const T& initializer) : T(initializer)
    {
    }
    

    并使用:

    Decorator<Base> d1((Base()));
    Decorator<Base> d2(Base("decorated"));
    Decorator<Derived> d3(Derived("derived",777));
    

    同样在C ++ 0x中,您可以完美地将Decorator的构造函数中的任意数量的参数转发到基础构造函数,从而有效地使用像往常一样干净:

    Decorator<Base> d1;
    Decorator<Base> d2("decorated");
    Decorator<Derived> d3("derived",777);