函数调用如何处理构造函数初始化列表中未初始化的数据成员对象
How function call is working on an unitialized data member object in constructor's initilalizer list
考虑下面的程序,
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A constructor\n"; }
void f()
{
cout << "A used\n";
this->i++;
}
private:
int i;
};
class B
{
public:
B(A & a1)
{
cout << "B constructor\n";
a1.f();
}
};
class Z
{
public:
Z() : a_(), b_(a_) {}
private:
B b_;
A a_;
};
int main() {
Z z;
return 0;
}
下面是它产生的输出,
B constructor
A used
A constructor
我的问题,
由于数据成员对象是按照它们在 class 中声明的顺序创建的,因此 b_
将首先创建。但是它如何能够在仍未创建的数据成员 a_
上调用函数?编译器是否执行某种优化以将对 f()
的调用转换为普通函数调用?如果是,那么 this->i++
是如何工作的?
当您明确指示编译器在某处传递对未初始化对象的引用时,编译器不会反对您。毕竟,您传递给它的函数可能用于实际初始化对象。
但是,访问未初始化的数据,例如您的 this->i++;
,会导致未定义的行为。
考虑下面的程序,
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "A constructor\n"; }
void f()
{
cout << "A used\n";
this->i++;
}
private:
int i;
};
class B
{
public:
B(A & a1)
{
cout << "B constructor\n";
a1.f();
}
};
class Z
{
public:
Z() : a_(), b_(a_) {}
private:
B b_;
A a_;
};
int main() {
Z z;
return 0;
}
下面是它产生的输出,
B constructor
A used
A constructor
我的问题,
由于数据成员对象是按照它们在 class 中声明的顺序创建的,因此 b_
将首先创建。但是它如何能够在仍未创建的数据成员 a_
上调用函数?编译器是否执行某种优化以将对 f()
的调用转换为普通函数调用?如果是,那么 this->i++
是如何工作的?
当您明确指示编译器在某处传递对未初始化对象的引用时,编译器不会反对您。毕竟,您传递给它的函数可能用于实际初始化对象。
但是,访问未初始化的数据,例如您的 this->i++;
,会导致未定义的行为。