在初始化列表中初始化许多对象成员变量
Initializing many object member variables in initializer list
我有一个关于在一个类中初始化多个对象成员的最佳实践的问题。这个问题的背景是一个嵌入式项目,我经常使用引用和构造函数注入:
class ComponentA
{
public:
ComponentA(SomeComponent1& dependency1, SomeComponent2& dependeny2)
private:
/* ... */
};
现在假设我有许多其他类,如ComponentA,它们必须在一个类中实例化:
class Layer
{
private:
ComponentA componentA; // Composition
/* ...and many other components */
public:
Layer(SomeComponent1& firstDepOfA, SomeComponent2& secondDepOfA, ...) :
componentA(firstDepOfA, secondDepOfA), /* other components */
};
我正在考虑使用构建器模式来减少复杂性:
class Layer
{
private:
ComponentA componentA; // Composition
/* ...and many other components */
/* now private */
Layer(SomeComponent1& firstDepOfA, SomeComponent2& secondDepOfA, ...) :
componentA(firstDepOfA, secondDepOfA), /* other components */
public:
ComponentAIntf& getComponentA ( ... );
class Builder
{
private:
SomeComponent1* firstDepOfA;
SomeComponent2* secondDepOfA;
/* other dependencies/constructor parameters */
public:
/* returns Builder, because we want a fluent api */
Builder& setFirstDepOfA(SomeComponent1* dep) {firstDepOfA = dep; return *this;}
Builder& setSecondDepOfA(SomeComponent2* dep) {secondDepOfA = dep; return *this;}
Layer& build()
{
/* check parameters */
...
/* create instance, constructor will be called once when scope is entered */
static Layer layer(/* parameters */);
return layer;
}
}
};
构造器类的主要缺点是成员实例的构造器参数是重复的。我认为这也可以实现与模板,但我还没有找到任何资源。举个例子就好了,但是我想避免使用模板。任何帮助都是感激的。我想我错过了什么……
Thanks in advance
在这里使用Builder模式是危险的,因为您可能在设置所有依赖项之前调用build
。(使用构造函数注入的原因之一是防止类在没有显式指定其所有依赖项的情况下被实例化。)
你应该把ComponentA
注入到Layer
中,而不是让它直接产生依赖。例如:
class Layer
{
private:
ComponentA& componentA; // Composition
/* ...and many other components */
public:
Layer(ComponentA& componentA, ...) :
componentA(componentA), /* other components */
};
当使用依赖注入时,你最终应该有一个组合根,在那里你实际构建你的对象图。(这是所有依赖注入实际发生的地方。)
如果您需要按需实例化ComponentA
,那么您可以考虑将责任委托给工厂:
class ComponentFactory
{
private:
SomeComponent1* firstDepOfA;
SomeComponent2* secondDepOfA;
/* other dependencies/constructor parameters */
public:
ComponentFactory(SomeComponent1* firstDepOfA, SomeComponent2* secondDepOfA, ...) :
firstDepOfA(firstDepOfA), secondDepOfA(secondDepOfA), ...
{
}
ComponentA CreateComponentA()
{
return ComponentA(firstDepOfA, secondDepOfA);
}
...
};
class Layer
{
private:
ComponentFactory& componentFactory; // Composition
/* ...and many other components */
public:
Layer(ComponentFactory& componentFactory, ...) :
componentFactory(componentFactory), /* other components */
void DoSomethingThatUsesComponentA()
{
ComponentA = componentFactory.CreateComponentA();
...
}
};
相关文章:
- 为什么在C++中首先初始化成员类
- 是否可以防止省略聚合初始化成员?
- 正在复制具有未初始化成员的结构
- 使用大括号或括号初始化成员变量
- C++结构:强制初始化成员?
- C++中未初始化成员布尔变量的默认值是多少?
- 使用默认值初始化成员引用
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- C++使用 { } 初始化成员变量
- 如何根据构造函数参数使用超类类型初始化成员变量?
- OpenGL C++:VBO 的结构包装器不会初始化成员
- 有没有办法在Brace中初始化成员
- 从现有 istream 或类本身创建的 istream 初始化成员 istream
- 从其后声明的另一个成员数据初始化成员数据是否为未定义行为
- 通常应用方法,使用带有构造函数委托的 SFINAE 通过类模板的构造函数初始化成员
- 如何在嵌套类中初始化成员?C
- 是否可以在构造函数主体中初始化成员变量,而不是初始值设定项列表
- 编译器错误,因为构造函数必须显式初始化成员
- 如何使用成员函数初始化成员函数指针
- C 如何使用隐藏的默认构造函数初始化成员