据我所知,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派生
答案 0 :(得分:3)
这就是为什么C ++ 0x包含能够安全地转发任意数量的元素的原因:
template <typename T>
struct Decorator: T
{
template <typename... Args>
Decorator(Args&&... args): T(args...) {}
};
干净地转发论据。请查看ideone!
答案 1 :(得分: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);