C++ 当仍有引用时调用析构函数

C++ 当仍有引用时调用析构函数,c++,C++,从早期的一些重要文章(如)中,我了解到引用可以延长临时对象的寿命。所以,我决定亲自尝试一下,并得到了一个(对我来说)意想不到的结果。代码如下: #include <iostream> using namespace std; class B { public: B() {cout << "Constructor of B" << endl;} ~B() {cout << "Destructor of B" << endl;}

从早期的一些重要文章(如)中,我了解到引用可以延长临时对象的寿命。所以,我决定亲自尝试一下,并得到了一个(对我来说)意想不到的结果。代码如下:

#include <iostream>
using namespace std;

class B {
public:
  B() {cout << "Constructor of B" << endl;}
  ~B() {cout << "Destructor of B" << endl;}
  void methodB(){cout << "B is alive!" << endl;}
};

class A {
public: 
  A() {cout << "Constructor of A" << endl;}
  ~A() {cout << "Destructor of A" << endl;}
  B &methodA() {
    cout << "Entering methodA()" << endl;
    B b;
    B &a = b;
    cout << "Exiting methodA()" << endl;
    return a;
  }
};

int main() {
  A a;
  B &b = a.methodA();
  cout << "After the call to methodA()" << endl;
  b.methodB();
  return 0;
}
请注意对methodB()的调用是如何在执行B的析构函数之后执行的。这种行为的解释是什么

我了解到引用可以延长临时对象的寿命

代码中没有对临时对象的引用。从
a::methodA()
返回后,将返回对局部变量的引用,该局部变量将被销毁。打印“B是活动的!”只是因为在
B::methodB()
中没有引用任何
B
的成员变量。这是无效的,但它可能(也可能不)起作用


调用
b.methodB()
基本上是调用一个函数,该函数具有类型为
b*const
和值为
&b
的隐式隐藏第一个参数。在您的例子中,
b
对象已被销毁(您看到析构函数已被执行),
&b
指向堆栈上的某个内存,该内存在对象处于活动状态时放置在该内存中,但由于您没有引用任何
b
的成员,因此该指针永远不会被取消引用,并且可以正常工作(尽管您永远不应该依赖于此).

您的示例中有不同的
A
B
。他们是无关的!在methodA()中,返回对局部变量的引用。编译器应该对此发出警告,但不要这样做。您正在返回对堆栈上变量的引用。在methodA中初始化的B在方法末尾被销毁。然后返回一个指向垃圾数据的引用。您看到的“B的析构函数”是在methodB()中创建的本地B被销毁,这是意料之中的。我不明白您的意思。正如输出所证明的,A的构造函数只被调用一次,B的构造函数也是如此。这不是意味着每个类只有一个实例吗?局部变量不是一种临时对象吗?(事实上,局部变量的作用域更大:临时对象的作用域只是它出现的表达式)。它们之间的主要区别是什么?(即,为什么局部变量的销毁不能像有引用时临时对象的销毁一样推迟?)不,局部变量和临时变量是不同的。C++标准的第12.2段[类。临时]描述了什么是临时的。
Constructor of A
Entering methodA()
Constructor of B
Exiting methodA()
Destructor of B
After the call to methodA()
B is alive!
Destructor of A