是否明确定义了未初始化对象的成员地址?

Fra*_*eux 5 c++ object-lifetime language-lawyer ctor-initializer member-access

请考虑以下示例.当bar被构造,它给它的基本类型(foo)构造的地址my_member.y,其中my_member是还没有被初始化的数据成员.

struct foo {
    foo(int * p_x) : x(p_x) {}
    int * x;
};

struct member {
    member(int p_y) : y(p_y) {}
    int y;
};

struct bar : foo
{
    bar() : foo(&my_member.y), my_member(42) {}
    member my_member;
};

#include <iostream>

int main()
{
    bar my_bar;
    std::cout << *my_bar.x;
}
Run Code Online (Sandbox Code Playgroud)

这个定义得很好吗?获取未初始化对象的数据成员的地址是否合法?我发现了一个关于传递对未初始化对象的引用的问题,但它并不完全相同.在这种情况下,我在未初始化的对象上使用成员访问运算符 ..

这是真的,一个对象的数据成员的地址不应该被初始化改变,但这并不一定能使服用很好地定义了地址.此外,成员访问运营商的ccpreference.com页面有这样的说法:

即使没有必要,也会评估两个运算符的第一个操作数(例如,当第二个操作数命名为静态成员时).

我理解这意味着在&my_member.y my_member将被评估的情况下,我认为这很好(int x; x;似乎很好),但我找不到文件来支持它.

Pas*_* By 7

首先让我们提出准确的问题.

你正在做的是没有使用未初始化的对象,你正在使用一个不在其生命周期内的对象.my_member是在之后建造的foo,因此其寿命my_member尚未开始foo(&my_member.y).

来自[basic.life]

在对象的生命周期开始之前但在对象将占用的存储空间被分配之后[...],可以使用引用原始对象的任何glvalue,但仅限于有限的方式.[...]这样的glvalue指的是已分配的存储空间,并且使用不依赖于其值的glvalue的属性是明确定义的.如果出现以下情况,该程

  • glvalue用于访问对象,或[...]

在这里访问它意味着要么读取或修改对象的值.

my_member产量的评估是一个左值,没有必要转换为prvalue,因此它保持左值.同样,评估my_member.y也是一个左值.然后我们得出结论,没有访问任何对象的值,这是明确定义的.