Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么从临时初始化的引用成员仍然可读?_C++_Reference_Initialization - Fatal编程技术网

C++ 为什么从临时初始化的引用成员仍然可读?

C++ 为什么从临时初始化的引用成员仍然可读?,c++,reference,initialization,C++,Reference,Initialization,可能重复: 这个问题与我刚才问的另一个问题直接相关: 假设我们有一个类,该类具有某个其他类的引用成员,该类被初始化为构造函数中的临时变量: #include <iostream> struct B { B(int new_x = 10) : x(new_x) { std::cout << "B constructed\n"; } ~B() { std::cout << "B destroyed\n"; } public: int

可能重复:

这个问题与我刚才问的另一个问题直接相关:

假设我们有一个类,该类具有某个其他类的引用成员,该类被初始化为构造函数中的临时变量:

#include <iostream>

struct B
{
    B(int new_x = 10) : x(new_x) { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destroyed\n"; }

public:
    int x;
};

struct A
{
    A()
    : b( B(23) )
    {
        std::cout << "A constructed\n";
    }

    void Foo()
    {
        std::cout << "A::Foo()\n";
    }

    ~A()
    {
        std::cout << "A destroyed\n";
    }

public:
    const B& b;
};

int main()
{
    A a;
    a.Foo();
    cout << "x = " << a.b.x << endl;
}

看起来,即使临时文件被销毁,因此引用成员应该无效,引用成员的整数字段仍然是可读的。为什么它仍然有效?

未定义的行为。在您的情况下,临时
B
先前占用的内存在引用之前不会被覆盖。下次运行程序时,任何事情都可能发生

请注意,表面上相似的

const B &b = B();

有明确的行为;临时
B
的生存期通过引用绑定来延长。这只适用于引用变量,而不适用于引用成员。

未定义的行为。在您的情况下,临时
B
先前占用的内存在引用之前不会被覆盖。下次运行程序时,任何事情都可能发生

请注意,表面上相似的

const B &b = B();

有明确的行为;临时
B
的生存期通过引用绑定来延长。这只适用于引用变量,而不适用于引用成员。

如果引用无效,并不意味着它不可读。这意味着它没有引用有效的对象。它可能涉及也可能不涉及某个可访问内存;如果是的话,你可能会发现,也可能不会发现记忆中包含了曾经存在过的任何物体的残余物


总之,行为是未定义的。

如果引用无效,并不意味着它不可读。这意味着它没有引用有效的对象。它可能涉及也可能不涉及某个可访问内存;如果是的话,你可能会发现,也可能不会发现记忆中包含了曾经存在过的任何物体的残余物


总而言之,行为未定义。

分配给临时
B
的内存现在无效,但尚未用于任何其他用途。这就是为什么您的读取会产生上次存在的值。但是,这是未定义的行为。运行valgrind应该可以精确定位错误的位置


如果您想知道“怎么可能”,这里有一个解释,说明在非常类似的情况下会发生什么。

分配给临时
B
的内存现在无效,但尚未用于任何其他用途。这就是为什么您的读取会产生上次存在的值。但是,这是未定义的行为。运行valgrind应该可以精确定位错误的位置


如果你想知道“这怎么可能”,这里有一个解释,说明在非常相似的情况下会发生什么。

这是未定义的行为。没有“为什么”。内存仍然包含值
23
。请看Eric Lippert的杰出答案:也回答了您的问题。投票以重复方式关闭。在中间添加两个函数调用,您可能会得到一些垃圾…这是未定义的行为。没有“为什么”。内存仍然包含值
23
。请看Eric Lippert的杰出答案:也回答了您的问题。投票以重复方式关闭。在中间添加几个函数调用,您可能会得到一些垃圾。。。