如何使用孩子的成员初始化父母?
Posted
技术标签:
【中文标题】如何使用孩子的成员初始化父母?【英文标题】:How to initialize parent using member of child? 【发布时间】:2015-07-26 22:08:13 【问题描述】:我有一个需要初始化的类:
//Parent.h
class Parent
public:
Parent(Image image);
private:
const Image parentImage;
//Parent.cpp
Parent::Parent(Image image) : parentImage(image)
//Child.h
#import "Parent.h"
class Child : public Parent
public:
Child(int c);
private:
Camera childCamera;
//Child.cpp
Child::Child(int c) : Parent(this->childCamera.getImage()), childCamera(c)
Camera
需要先初始化,然后才能从中检索图像。 Parent
存储来自相机的图像,即const
,子级存储Camera
。如何创建Child
?我无法更改Parent
,因为还有其他子类以其他方式初始化Parent
。 Child
可以改,但是Camera
不能复制,Child
确实需要存储Camera
。
编辑:如果这是最干净的解决方案,我可以将构造函数添加到 Parent
。
【问题讨论】:
什么是this->childDataSource.getImage()
?您的代码显示 childCamera
和 Parent
之间没有依赖关系
对不起,应该是this->childCamera.getImage()
。真实情况有更多的成员等等,我在简化的时候出错了。
en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member
【参考方案1】:
你不能这样做。
根据标准(12.6.2/10)初始化顺序为:
——(...)
——然后,直接基类在声明中初始化 按照它们出现在基本说明符列表中的顺序(无论 mem-initializers 的顺序)。
——那么,非静态数据成员是 按照它们在类定义中声明的顺序进行初始化 (同样不管 mem-initializers 的顺序如何)。
——最后, 构造函数体的复合语句被执行。
因此,在您的 Child
构造函数内存初始化列表中,对于 Parent
初始化器,您不能使用任何依赖于 Child
成员变量的东西,因为此时这些变量是未初始化的。
但是,您可以使用 Child 构造函数的参数,例如:
Child::Child(int c) : Parent(c.getImage()), childCamera(c)
当然,前提是相机对象的每个副本都将返回与原始对象相同的图像。
另一种选择是使用来自辅助类的多重继承(使用上面标准引用的第二个破折号)。但这更棘手,无论如何也需要相机对象的副本。
【讨论】:
【参考方案2】:鉴于您列出的所有设计约束,一种合理的解决方案是在 Child 外部构造一个 Camera,然后将其传递给 Child 的构造函数。然后孩子将拥有它。
所以这个类可以写成这样:
class Child : public Parent
public:
Child(Camera* camera);
private:
std::unique_ptr<Camera> childCamera;
//Child.cpp
Child::Child(Camera* camera)
: Parent(camera->getImage()), childCamera(camera)
然后用作:
Camera* camera = new Camera;
Child child(camera);
【讨论】:
如果Child
构造函数采用unique_ptr<Camera>
会更好。【参考方案3】:
不,你不能。你不能使用任何依赖 Child 作为 Parent 的东西。
【讨论】:
以上是关于如何使用孩子的成员初始化父母?的主要内容,如果未能解决你的问题,请参考以下文章