如何使用子对象的成员初始化父对象
How to initialize parent using member of child?
我有一个需要初始化的类:
//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
,如果这是最干净的解决方案。
你不能这么做。
根据标准(12.6.2/10),初始化顺序为:
— (...)
-然后,直接基类在声明中初始化按照它们在基本指定符列表中出现的顺序排序(不管它们的
-则非静态数据成员为按照在类定义中声明的顺序初始化(同样,不考虑内存初始化式的顺序)。
——最后,执行构造函数体的复合语句。
所以在Child
构造函数的初始化列表中,对于Parent
初始化器,不能使用任何依赖于Child
成员变量的东西,因为它们在那一刻被初始化了。
但是,您可以使用Child构造函数的参数,例如:
Child::Child(int c) : Parent(c.getImage()), childCamera(c) {}
当然,如果Camera对象的每个副本都返回与原始对象相同的图像,则
。
另一种选择是使用来自辅助类的多重继承(使用上面标准引号的第二个破折号)。但这是更棘手的,无论如何也需要相机对象的副本。
考虑到您列出的所有设计约束,一个合理的解决方案是在Child的外部构造一个Camera,然后将其传递给Child的构造函数。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的元素来代替Parent
您可以使用Base From Member习语来实现这一点。基本上,你创建一个中间的持有者类/结构来保存曾经在基类中的变量,然后你首先从持有者类继承子类,然后从基类继承子类。使用该方法,您可以初始化父
当您运行下面的代码时,您将看到在有问题的情况下,基类在初始化时没有获得预期的值。但在解决方案中,它是按预期初始化的。让我知道这是否适合你。
#include "fmt/core.h"
struct TempStruct
{
explicit TempStruct(int temp) : tempI_(temp)
{
fmt::print("TempStruct {} n", tempI_);
}
int tempI_{33};
};
class BaseClass
{
public:
explicit BaseClass(TempStruct* pTemp)
{
fmt::print("BaseClass tempstruct {}n", pTemp->tempI_);
}
};
class ChildClass : public BaseClass
{
public:
// Below code doesn't work as expected. BaseClass initilizers first and then
// TempStruct. So BaseClass doesn't get TempStruct with 5. Field
// 'tempStruct_' will be initialized after base 'BaseClass' [-Wreorder-ctor]
ChildClass() : tempStruct_{5}, BaseClass(&tempStruct_)
{
}
private:
// Member initialize tempStruct_ to 10;
TempStruct tempStruct_{10};
};
// Solution
struct TempStructHolder
{
TempStructHolder(int i) : tempStruct_{i}
{
}
TempStruct tempStruct_{0};
};
class SolutionChildClass : public TempStructHolder, public BaseClass
{
public:
SolutionChildClass() : TempStructHolder(39), BaseClass(&tempStruct_)
{
}
};
int main()
{
fmt::print("Problem n");
[[maybe_unused]] const ChildClass c;
fmt::print("Solutin n");
[[maybe_unused]] const SolutionChildClass sc;
}
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 对象初始化中是否允许指向此成员的指针?
- 对象初始化后在C++中显示 char 数组时的异常行为
- 为什么两种不同的对象初始化方式给出不同的输出
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- afxmem.cpp中的对象初始化差异
- 删除通过取消引用新对象初始化的对象
- 如何使用sregex_token_iterator对象初始化向量
- 关于默认构造函数,对象初始化/使用C++ OOP
- C++ 基元类型初始化与对象初始化
- 哪个函数负责C++全局范围内的类对象初始化?
- C++中构造函数的对象初始化出现问题
- 如何修复模板 BST 类的对象初始化
- 无法在 QML/C++ 中使用绑定对象初始化 UI
- 为什么参数可以在对象初始化时通过赋值运算符传递给构造函数?
- 类对象初始化的二维向量
- GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
- 对象初始化
- 类对象初始化
- 使用从另一个类继承的类的对象初始化成员对象