基本访问中的工厂方法保护ctor in derived

时间:2014-09-22 14:55:48

标签: c++ constructor shared-ptr factory

我希望所有派生自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;
// ...
};

我想避免将每个派生类声称为朋友,我该怎么办?

1 个答案:

答案 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
     ...
};