Вы ставите себя в море проблем с обслуживанием.
В вашем первом примере ...
есть действительно не нужнодля конструктора шаблона.Он обозначается как
// Parse any type, which needs to be derived from "abstract" and create a copy.
Пользователь уже может сделать это, создав сам экземпляр и передав его первому конструктору.
Также с помощью этого:
// Free memory in destructor.
Вы прямо говорите, что понятия не имеете, как использовать этот класс.Поскольку ваш первый пример написан, вам нужно решить: использовать экземпляр, созданный снаружи, или использовать экземпляр, созданный внутри.Это сбивает с толку видеть интерфейс с одним ctor, принимающим указатель, и другим ctor, принимающим ссылку, оба по существу одного и того же типа.
На мой взгляд, единственный приемлемый способ использования экземпляра, созданного извне,не должен управляться памятью или экземпляр, созданный изнутри, который будет управляться памятью, - это когда есть ctor по умолчанию, который может инициализировать внутренний указатель на разумное значение (но это не похоже наслучай здесь, поскольку вы хотите скопировать другой экземпляр):
template <typename T>
class user_of_abstract
{
bool m_owner_;
abstract* m_abstract;
public:
user_of_abstract_base(abstract* a = NULL)
: m_owner(a == NULL)
, m_abstract(m_owner ? new T(): a)
{
}
~user_of_abstract_base()
{
if (m_owner)
{
delete m_abstract;
}
}
}
Ваш второй пример ...
превосходит первый, так как вы неt явно смешивать управление памятью со ссылкой на память.Вы позволяете shared_ptr
делать это неявно.Очень хорошо, вот для чего это.
Однако, поскольку у вас есть требование, чтобы use_sec_func
брал в качестве входных данных вывод use_fst_func
, вы далеки от безопасного берега моря технического обслуживания.проблемы.
Например, что произойдет, если use_fst_func
в экземпляре выдает исключение и use_sec_func
позже будет вызван в этом же экземпляре?
Как вы ожидаете, что важная информация "Всегда вызывайте А до Б. И только один раз. И передайте результат А Б.должен распространяться среди пользователей класса через 2 года?
Почему use_sec_func
нельзя просто позвонить use_fst_func
?
Что касается вашего третьего примера ...
Можете ли вы дать 1 единственный сценарий, когда вы хотите использовать это вместо простого вызова функций экземпляра?