首页 > 解决方案 > C ++使派生类只能从工厂/基类实例化

问题描述

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

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

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
}

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

标签: c++oopinheritancedesign-patterns

解决方案


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

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


推荐阅读