我希望所有派生自Initable
的对象在销毁时调用terminate()
。为此,我使用自定义删除器创建shared_ptr
。
我的问题是我无法访问派生类的受保护的ctor,以便在Initable
工厂方法中创建实例。
应该保护ctor,以防止在不使用工厂方法的情况下创建实例。
class Initable {
public:
virtual void terminate() = 0;
template<typename T, typename... Ts>
static shared_ptr<T> make_initable(const Ts &... args) {
return shared_ptr<T>(new T(std::forward<const Ts>(args)...), [] (Initable * aptr) {
cout << "custom deleter" << endl;
});
}
};
class B : public Initable {
friend class Initable;
// ...
};
我想避免将每个派生类声称为朋友,我该怎么办?
答案 0 :(得分:1)
友谊不是:
我认为这让您可以选择帮助您的用户发现他错过了向Initable类声明友谊。您不能使用模板专门化,因为友元声明需要在类范围内发生,模板声明需要在命名空间范围内发生。
一种方法是:
#define DECLARE_INITABLE \
constexpr static bool is_Initable_friend = true;\
friend class Initable;
class Initable {
public:
virtual void terminate() = 0;
template<typename T, typename... Ts>
static shared_ptr<T> make_initable(const Ts &... args) {
static_assert(T::is_Initable_friend, "Please call DECLARE_INITABLE in your class declaration");
return shared_ptr<T>(new T(std::forward<const Ts>(args)...), [] (Initable * aptr) {
cout << "custom deleter" << endl;
});
}
};
class B : public Initable {
// DECLARE_INITABLE
...
};