2015-10-21 2 views
3

мне нужно вставить клон и создать функции-члены моего класса hieararchyКак получить доступ к конструктору базового класса при использовании CRTP

class Base 
{ 
protected: 
    const int x_; 
public: 
    Base() : x_(0) {} 
    Base(int x) : x_(x) {} 
}; 

Я думал, что CRTP может быть способ, как сэкономить ввод и избежать ошибок.

template <typename Derived> 
class CRTP_Iface : public Base 
{ 
public: 
    virtual Base *create() const { return new Derived(); } 
    virtual Base *clone() const { return new Derived(static_cast<Derived const&>(*this)); } 
}; 

К сожалению, я не могу получить доступ к конструктору базового класса для инициализации членов const.

class D1 : public CRTP_Iface<D1> 
{ 
public: 
    D1() : Base() {} 
    D1(int x) : Base(x) {} 
}; 

class D2 : public CRTP_Iface<D2> 
{ 
public: 
    D2() : x_(0) {} 
    D2(int x) : x_(x) {} 
}; 

int main() 
{ 
    D1 a; 
    D2 b; 

    return 0; 
} 

Есть ли простой способ, как решить эту проблему?

ответ

3

Просто добавьте все необходимые конструкторы в CRTP_Iface.

public: 
    CRTP_Iface() : Base() {} 
    CRTP_Iface(int x) : Base(x) {} 

При использовании C++ 11 это становится еще проще:

public: 
    using Base::Base; 

Тогда у вас есть:

class D1 : public CRTP_Iface<D1> 
{ 
public: 
    D1() : CRTP_Iface() {} 
    D1(int x) : CRTP_Iface(x) {} 
}; 

... что может быть лучше написана на C++ 11:

class D1 : public CRTP_Iface<D1> 
{ 
public: 
    using CRTP_Iface<D1>::CRTP_Iface; 
}; 

(не уверен, что необходимо либо с левой стороны или правая рука ::, AFAIR некоторого complilers нравится более строгий)

1

Вы можете унаследовать конструктор класса Base в шаблоне CRTP_Iface<>, а затем вызвать его конструктор в производных классов:

template <typename Derived> 
class CRTP_Iface : public Base 
{ 
protected: 
    using Base::Base; 

public: 
    virtual Base *create() const { return new Derived(); } 
    virtual Base *clone() const { return new Derived(static_cast<Derived const&>(*this)); } 
}; 

class D1 : public CRTP_Iface<D1> 
{ 
public: 
    D1() : CRTP_Iface() {} 
    D1(int x) : CRTP_Iface(x) {} 
}; 

live example

+0

что произойдет в вашем коде, если выполнить 'D1 a; auto c = a.create(); delete c; ? –

+0

@FengWang Нужно добавить виртуальный деструктор для 'Base': http://melpon.org/wandbox/permlink/WoxkGgrhoAoAzNOt –

Смежные вопросы