我希望派生类的构造函数能够从作为此构造函数参数的对象中分配一些数据,而参数类是构造对象本身的父类。
此代码正常运行。但我想知道这是否正确,或者我只是幸运,应该期望在不同的运行时条件下崩溃。 C ++如何在复制期间计算Args
字段的有效地址,因为编译器不知道这是"独立的" Args
对象或更大对象的一部分? dynamic_cast
如何在这里实际工作,因为对象不是多态的?
#include <iostream>
using namespace std;
struct Base {
int FieldBInt;
double FieldBDouble;
Base () : FieldBInt(10), FieldBDouble(13.5) { }
};
struct Args {
int FieldAInt;
string FieldAString;
};
struct Derived : public Base, public Args {
int FieldDInt;
double FieldDDouble;
explicit Derived (const Args & args) : Base(), FieldDInt(40), FieldDDouble(14.5) {
Args * castedThis = dynamic_cast<Args *>(this);
*castedThis = args;
}
};
int main(int argc, char *argv[]) {
Derived d ({50, "Text"});
cout << d.FieldBInt << " " << d.FieldBDouble << endl
<< d.FieldAInt << " " << d.FieldAString << endl
<< d.FieldDInt << " " << d.FieldDDouble << endl;
}
代码打印(正确):
10 13.5
50 Text
40 14.5
答案 0 :(得分:2)
派生类使用多重继承从Base和Args类继承。
使用Args * castedThis = dynamic_cast<Args *>(this);
,您将获得指向d。
可以预期Derived对象d以它的Base部分开头,然后是它的Args部分,后跟它自己的成员。我不知道它是否符合标准要求。
在任何情况下,dynamic_cast<Base *>(this)
和dynamic_cast<Args *>(this)
都会为您提供不同的地址。
*castedThis = *(&args);
将导致生成struct Args的复制赋值运算符。此复制赋值运算符将复制Args成员。
在初始化程序列表中初始化Args时,其他用户建议您生成并使用复制构造函数而不是复制赋值运算符。
在您的代码中,d的Arg部分首先默认初始化,然后复制分配。
当然,按照人们的建议初始化初始化列表中的基本成员会更清楚。
编辑回答:dynamic_cast如何在这里实际工作,因为对象不是多态的?
在这种情况下,static_cast和dynamic_cast可以在这里使用,因为它们都可以作为转换广告,它们将转换指针。使用static_cast检查它是否可以转换将在编译时完成,而dynamic_cast将在运行时完成(在这种情况下没有任何好处)。
从cppreference中读取我认为C-Style cast or explicit cast也会起作用,因为它似乎应该作为static_cast。
所以这种情况多态性(runtime polymorphism)无关。在编译时或运行时进行类型检查和转换也是如此。
注意:您在问题的原始编辑中放置的代码*this = *(&args);
给出了以下编译器错误:与'operator ='不匹配(操作数类型是'Derived'和'const Args “)。该代码调用一个asignment操作符,该操作符可以从Args对象为Derived对象赋值,并且我们没有定义任何函数来执行此操作。
答案 1 :(得分:0)
因为编译器不知道这是否是“独立”的Args对象 或者是较大物体的一部分?
您直接从中继承。编译器清楚地知道。实际上,在这种情况下,标准将dynamic_cast
定义为static_cast
,这与Args* castedThis = this;
几乎相同。