提问人:Yusuf Tarık Günaydın 提问时间:3/9/2021 更新时间:3/9/2021 访问量:63
为什么在对象初始化期间,此指针指向成员构造函数中的错误对象?
Why does this pointer points to wrong object inside member's constructor during object initialization?
问:
以下代码将同一地址打印两次:
#include <iostream>
struct B
{
B()
{
std::cout << this << std::endl;
}
};
struct A
{
A()
{
std::cout << this << std::endl;
}
B b;
};
int main()
{
A a;
}
为什么此指针指向 B 构造函数中的 A?
答:
2赞
Serge Ballesta
3/9/2021
#1
B 是一个空类,因此它是一个标准布局类。
A 只包含一个(非静态)成员,即 B。它没有虚拟方法。因此,它也是一个标准的布局类。
对于标准布局类,标准要求对象的地址与其第一个子对象的地址相同。
因此,您看到相同的地址是正常的,并且 A 对象及其 B 子对象是指针可互换的。
小心接下来是原来的错误答案。它仅供参考,但完全是错误的 它只是一个实现细节。第一个子对象保证仅在标准布局类中具有与其包含对象相同的地址,而 A 和 B 都不是。
在这里,您的实现选择为两个对象提供相同的地址,但另一个实现可能使用不同的地址。
永远不要依赖实现细节......
评论
0赞
Caleth
3/9/2021
B
是空的,即 StandardLayout,并且只包含一个空的非静态数据成员,所以它也是A
0赞
Serge Ballesta
3/9/2021
@Caleth:你是对的,我错了。A 有一个非平凡的构造函数,不是一个平凡的类,但它没有虚拟方法,确实是标准布局。我把这两个概念混为一谈,给出了一个错误的答案。
0赞
Caleth
3/9/2021
不用担心:)它们是非常相似的概念
0赞
Caleth
3/9/2021
#2
这两个指针具有相同的值,但它们指向不同的对象。对象中有一个对象,它是B
A
A
这是由标准保证的,因为它们是 StandardLayoutType
- 所有非静态数据成员都具有相同的访问控制
- 真空真实
B
- True for
A
- 真空真实
- 没有虚拟函数或虚拟基类
- 对两者都为 True 和
A
B
- 对两者都为 True 和
- 没有引用类型的非静态数据成员
- 对两者都为 True 和
A
B
- 对两者都为 True 和
- 所有非静态数据成员和基类本身都是标准布局类型
- 真空真实
B
- True for
A
- 真空真实
- 没有两个(可能是间接的)相同类型的基类子对象
- 真空地为 和
A
B
- 真空地为 和
- 在同一类中声明所有非静态数据成员和位字段(全部在派生中或全部在某个基中)
- 真空真实
B
- True for
A
- 真空真实
- 没有一个基类子对象具有与 [复杂条件] 相同的类型
- 真空地为 和
A
B
- 真空地为 和
评论