我很惊讶地意外地发现以下方法是有效的:
#include <iostream>
int main(int argc, char** argv)
{
struct Foo {
Foo(Foo& bar) {
std::cout << &bar << std::endl;
}
};
Foo foo(foo); // I can't believe this works...
std::cout << &foo << std::endl; // but it does...
}
我将构造的对象的地址传递给它自己的构造函数。这看起来像是源代码级别的循环定义。标准是否真的允许您在对象构造之前将对象传递到函数中,或者这是未定义的行为?
我想这并不奇怪,因为所有的类成员函数都已经有一个指向其类实例的数据的指针作为隐式参数。并且数据成员的布局在编译时是固定的。
注意,我并不是在问这是不是有用或者是一个好主意;我只是修修补补地学习更多关于类的知识。
发布于 2015-09-16 20:51:39
在为待对象分配内存的点调用构造函数。此时,该位置上不存在任何对象(或者可能是具有简单析构函数的对象)。此外,this
指针指向该内存,并且该内存已正确对齐。
因为它是分配并对齐的内存,所以我们可以使用Foo
类型(即Foo&
)的左值表达式来引用它。我们可能还没有做的是从左值到右值的转换。只有在进入构造函数体之后才允许这样做。
在本例中,代码只是尝试在构造函数体内打印&bar
。在这里打印bar.member
甚至是合法的。由于构造函数体已经输入,因此Foo
对象存在,并且其成员可以被读取。
这给我们留下了一个小细节,那就是名称查找。在Foo foo(foo)
中,第一个foo
引入作用域中的名称,因此第二个foo
引用刚刚声明的名称。这就是为什么int x = x
是无效的,而int x = sizeof(x)
是有效的。
https://stackoverflow.com/questions/32608458
复制相似问题