我可以从类构造函数中将“this”作为指针传递给函数,并在构造函数返回之前使用它指向对象的成员吗?
这样做是否安全,只要在函数调用之前正确初始化所访问的成员?
举个例子:
#include <iostream>
class Stuff
{
public:
static void print_number(void *param)
{
std::cout << reinterpret_cast<Stuff*>(param)->number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(this);
}
};
void main() {
Stuff stuff(12345);
}
我认为这不起作用,但似乎。是这种标准行为,还是仅仅是未定义的行为?
答案 0 :(得分:32)
在C ++中实例化对象时,构造函数中的代码是最后执行的事情。所有其他初始化,包括超类初始化,超类构造函数执行和内存分配事先发生。构造函数中的代码实际上只是在构造对象后执行其他初始化。因此,在类的构造函数中使用“this”指针并假设它指向一个完全构造的对象是完全有效的。
当然,如果尚未在构造函数代码中初始化它们,仍需要注意未初始化的成员变量。
答案 1 :(得分:4)
您可以找到这个here(C ++常见问题解答)的好答案。
保证在构造函数的代码执行开始时构造所有继承的成员和调用类的成员,因此可以在其中安全地引用它。
主要问题是你不应该在this
上调用虚函数。大多数时候我都试过它,最后调用基类的函数,但我相信标准说结果是未定义的。
答案 2 :(得分:0)
作为对所呈现代码的旁注,我会反而模仿void*
:
class Stuff
{
public:
template <typename T>
static void print_number(const T& t)
{
std::cout << t.number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(*this);
}
};
如果t
的类型没有number
成员,则会出现编译错误。
答案 3 :(得分:-2)
安迪,我认为你对标准的未定义部分是错误的。
当你在构造函数中时,“this”是一个指向对象的指针,该对象的类型是你正在创建的对象的基类,这意味着虚拟函数部分地在将调用基类,并且不会遵循虚拟表中的指针。
C++ Faq Lite ...
中的更多信息