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

Is this a valid workaround to the constructor issue with mixins?

本文关键字:有效 方法 问题 构造函数 解决 mixin      更新时间:2023-10-16

据我所知,mixin存在一个问题,如果你想使用非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衍生

  1. 如果在构造过程中抛出异常,则会导致内存泄漏
  2. 基类必须有一个默认构造函数才能首先构造,然后赋值

更好的做法:

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

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

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

它干净地提出了论点。在ideone上看看吧!