C++ 使派生类只能从工厂/基类实例化

zup*_*zt3 1 c++ oop inheritance design-patterns

我正在建模类来表示带有子模块的模块等等。我使每个子模块都从基类(模块)派生。

但现在我想让除了某些特定方法(如工厂模式)之外的任何地方都无法创建子模块 - 以便为子模块提供一些配置。看代码:

class Module
{
    public:
        template<typename T, typename... Args>
        std::shared_ptr<T> addSubModule(Args&&... args)
        {
            std::shared_ptr<T> module = std::make_shared<T>(args...);

            children.emplace_back(module);
            module->parent = this;

            return module;
        }

    protected:
        Module* parent = this;
        std::vector<std::shared_ptr<Module>> children;
};


class SomeSubModule : public Module
{
    public:
        SomeSubModule(int param1, int param2)
        {
            // ... some init
        }
};


void Usage()
{
    Module rootModule;

    rootModule.addSubModule<SomeSubModule>(1, 2);   // <-- Way 1) This is what I want
    SomeSubModule sub(1, 2);                        // <-- Way 2) This also works, but I want to prevent it
}
Run Code Online (Sandbox Code Playgroud)

我想让“方式 1”成为唯一的方式(这样我就可以在 addSubModule 中执行一些初始化操作,例如将新创建的模块添加到子向量中,初始化父指针等)。
按照我写的方式,“方式2”仍然是可能的,但我不想要它。

JDł*_*osz 5

一般来说,当我们想要控制类的构造时(例如,它只使用智能指针分配堆,从不声明为本地值),您可以通过不将构造函数公开来实现!

构造函数应该是非公共的,并且只能由应该使用它的其他代码访问。简单的方法是使用friend. 在 Boost 中,您可以找到更复杂的方法,例如声明另一种类型作为访问路径,这对于处理大量子模块非常方便。