2011-06-22 24 views
1

据我所知,mixin存在一个问题,如果你想使用除无参数构造函数之外的东西,那么你使用你的mixin的对象必须有一个公共的构造函数签名,或者你必须使用初始化方法在你想使用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; 
} 

没有参数构造

装饰

X = 777衍生

+0

@Martin:你是什么意思b合法吗? – user487100

+0

@Martin:不是,虽然我会用两个阶段的方法:'T&me = * this; me = * initializer;'因为'static_cast'在这个方向上是不必要的。 –

+0

@Matthieu:这样行为>是 user487100

回答

3
  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<Base> d1; 
Decorator<Base> d2("decorated"); 
Decorator<Derived> d3("derived",777); 
+0

是的,使用复制构造函数似乎更好。根据我的经验,我并不知道你可以使用拷贝构造函数来初始化基类。谢谢。 – user487100

+0

我编辑了我的代码。谢谢。那么我刚刚阅读的信息是否过时?这样的变通方法是众所周知的还是人们只是在等待C++ 0x来获取所有ISO? – user487100

+0

@ user487100:可以通过使用不同数量的参数编写构造函数来近似C++ 03中的可变参数模板。您可以使用预处理器魔术来很好地完成它。 – ybungalobill

3

这就是为什么的C++ 0x包括转发,安全的能力,元件的任意数量的原因:

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

其中干净地转发参数。查看ideone

+0

非常漂亮。好主意也很好! – user487100

相关问题