gpt4 book ai didi

c++ - 对理解 C++ 代码的流程执行有一点帮助

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:34:40 25 4
gpt4 key购买 nike

我正在阅读 C++ Super-FAQ 中构造函数的初始化顺序来自网站 The C++ Programming Language。提供了以下代码。

#include <iostream>
class Y {
public:
Y();
void f();
};
Y::Y() { std::cout << "Initializing Y\n"; }
void Y::f() { std::cout << "Using Y\n"; }
class X {
public:
X(Y& y);
};
X::X(Y& y) { y.f(); }
class Z {
public:
Z();
protected:
X x_;
Y y_;
};
Z::Z()
: y_()
, x_(y_)
{ }
int main()
{
Z z;
return 0;
}

这段代码的打印序列是:

Using Y

Initializing Y

好吧,我只是无法理解这个打印序列是如何可能的,因为在类 Z 的构造函数中,首先实例化 Y 类的实例 y_ 然后实例化实例 x_ X级的就是这样。换句话说,如果要使用方法 Y::f() 首先,我需要实例化一个 Y,它肯定会调用它构造函数和打印例程 std::cout << "Initializing Y\n";

最佳答案

由于 X x_class Z 的定义中 Y y_ 之前出现,因此首先构造和初始化 x_ .无论您将成员放在初始化列表 Z::Z() : y_(), x_(y_) {} 中的顺序如何,x_ 仍然首先初始化。

因为 y_ 的构造函数还没有被调用,一些内部元素比如 vtable 将不会被初始化。实际上在 X 的构造函数中使用此对象可能会导致段错误。也许这个定义更适合您。

class Z {
public:
Z();
protected:
Y y_;
X x_;
};

因为 x_ 定义在 y_ 之后,y_ 将首先被调用,您可以在 x_ 中安全地使用它> 的构造函数。

您不妨阅读 Initialization order这篇文章的一部分。

编辑:C++ 重视速度并信任程序员,因此它不会尝试验证提供给它的参数。您可以将空指针转换为引用,然后使用该引用。

Y* p = 0;
X x(reinterpret_cast<Y&>(p));

这会编译,如果编译器不需要引用我们的空指针,它就不会失败。如果您将 f 设为虚拟,或尝试访问任何成员,那么这将导致段错误。

关于c++ - 对理解 C++ 代码的流程执行有一点帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41241275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com