2016-05-24 3 views
0
class ListItem 
{ 
    ListItem* GetPrev (); 
    ListItem* GetNext (); 
    // ... and many more 
}; 

class One : public ListItem 
{ 
    One* GetPrev() { return static_cast<One*>(ListItem::GetPrev()); } 
    One* GetNext() { return static_cast<One*>(ListItem::GetNext()); } 
    // ... and many more overrides 
}; 

class Two : public ListItem 
{ 
    Two* GetPrev() { return static_cast<Two*>(ListItem::GetPrev()); } 
    Two* GetNext() { return static_cast<Two*>(ListItem::GetNext()); } 
    // ... and many more overrides 
}; 

class Object : public One, public Two 
{ 
}; 

Цель этого класса заключается в том, чтобы объект класса был вставлен в два или более разных списка. Мой вопрос в том, как я могу выбрать один и два? Так как название класса также отображается как тип, возможно ли это? У меня это покрывается макросами, но можно ли это сделать с помощью шаблонов? Я не против, если структура кода немного изменится, но можно ли это сделать без макросов?Замена макросов определения классов с помощью шаблонов

+0

Есть два ['std :: list '] (http://en.cppreference.com/w/cpp/container/list) s? – Barry

ответ

0

Конечно, вы можете сделать ListItem шаблон:

template<class T> 
class ListItem 
{ 
    T* GetPrev (); 
    T* GetNext (); 
    // ... and many more 
}; 

class One : public ListItem<One> 

Это любопытно повторяющаяся модель шаблона.

+0

Удивительно, это именно то, что я искал. Это на самом деле перешло мне в голову, но я не знал, разрешено ли это и даже имеет имя, спасибо! –

0

Вы можете использовать любопытно повторяющийся шаблон шаблона и даже иметь ListItem родителей. Но, пожалуйста, рассмотреть вопрос об использовании какой-std::vector или std::list, нет необходимости изобретать списки шаблонов ... Тем более, что звонки с Object уровня должны выглядеть так:

Object o; 
One* prev = o.One::GetPrev(); 

Рабочий код (http://ideone.com/dbmwFZ):

struct ListItem 
{ 
    ListItem* GetPrev (); 
    ListItem* GetNext (); 
    // ... and many more 
}; 

template <typename T> 
struct ListItemT : ListItem 
{ 
    T* GetPrev() { return static_cast<T*>(ListItem::GetPrev()); } 
    T* GetNext() { return static_cast<T*>(ListItem::GetNext()); } 
}; 

struct One : ListItemT<One> 
{ 
}; 

class Two : public ListItemT<Two> 
{ 
}; 

class Object : public One, public Two 
{ 
}; 
+0

Отлично, спасибо за подробный код, проголосовали за другой ответ за его простоту, хотя, надеюсь, вы не против, оба ответа удивительны :) –

+0

@ user3721806 без проблем, если это помогает :) – Hcorg

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