c++ - 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”仍然是可能的,我不想要它。
解决方案
通常,当我们想要控制一个类的构造时(例如,它只使用智能指针分配堆,从不声明为本地值),您可以通过不公开构造函数来做到这一点!
构造函数应该是非公开的,并且只能由应该使用它的其他代码访问。简单的方法是使用friend
. 在 Boost 中,您可以找到更复杂的方法,例如声明另一种类型作为访问路径,这对于处理大量子模块非常方便。
推荐阅读
- reactjs - React SVG 组件:6:134 错误解析错误:意外的令牌,预期的“}”
- android - 当设备不使用 Xamarin Android 移动时,不会调用 ILocationListener.OnLocationChanged() 方法
- css - 为什么宽度为 100px 且 padding-bottom=100% 而不是 100px 的 div 的 padding-bottom
- sql - SQL Server:将变量连接成一个批量
- javascript - 读取文件名被删除
- javascript - '{ [key: string]: any; 类型的参数 }' 不可分配给“any[]”类型的参数
- sql - SQL Server:如果在一个表中插入一行,我如何编写触发器以在不同的表中插入同一行?
- spring - Websphere 8.5.5.12 - Spring Boot 不工作
- webdriver-io - 如何通过 wdio 访问子元素
- python - 我可能在流函数中遇到问题