Шаблон CRTP и enable_shared_from_this - PullRequest
2 голосов
/ 31 января 2012

В моем текущем коде у меня есть класс TNCPConnection, полученный из enable_shared_from_this:

class TNCPConnection : public boost::enable_shared_from_this<TNCPConnection> { ... };

Теперь мне нужно создать второй класс ETCPConnection, который будет делиться большим количеством кода с существующим классом TNCPConnection. Таким образом, очевидное решение состоит в том, чтобы иметь абстрактный базовый класс CPConnectionBase, который реализует общую функциональность.

Я знаю, что только один класс в иерархии наследования может быть производным от enable_shared_from_this. В поисках решения я наткнулся на шаблон CRTP, но я не уверен, правильно ли я это понял. Вот мой подход:

template <class Derived>
class CPConnectionBase : public boost::enable_shared_from_this<Derived>
{
public:

    CPConnectionBase(void) { }
    virtual ~CPConnectionBase(void) = 0 { }
};

class TNCPConnection : public CPConnectionBase<TNCPConnection> { ... };

class ETCPConnection : public CPConnectionBase<ETCPConnection> { ... };

Это правильный способ решить мою проблему? Будет ли подсчет ссылок работать правильно с этим подходом? В частности, я хотел бы знать, должен ли параметр шаблона enable_shared_from_this быть Derived (как в примере выше) или что-то вроде CPConnectionBase<Derived>?

1 Ответ

2 голосов
/ 31 января 2012

Если вы используете этот подход, каждый производный класс будет иметь свой собственный уникальный базовый класс.Даже если у них одинаковое имя, они будут разными экземплярами.Вы уверены, что наследование базового класса от enable_shared_from_this не предоставит возможность всем дочерним элементам?

Кроме того, which will share a lot of code with the existing ... class. является , а не непосредственным показателем использования наследования.В общем, наследовать для расширения, а не для повторного использования.Если весь базовый класс реализует общую функциональность, но не предоставляет общего интерфейса для двух классов, вам, вероятно, следует переосмыслить подход.Либо используйте состав и делегирование для общих методов, либо, если они не имеют непрерывного состояния, поместите общий код в (возможно, анонимные) пространства имен и вызовите их из необходимых вам функциональных классов.Вы не предоставили достаточно информации, чтобы точно определить, что вы пытаетесь сделать.

...