为什么派生类析构函数被调用,即使基类析构函数不是虚拟的,如果将对象创建为引用

Sur*_*uri 2 c++ virtual reference visual-c++

#include <iostream>
class Database
{
public:
   Database()
   {
      std::clog << "Database object created " <<std::endl ;
   }
   ~Database()
   {
      std::clog << "Database object destroyed " << std::endl;
   }
   virtual void Open(const std::string & ) = 0 ; 
} ;

class SqlServer : public Database
{
public:
   void Open(const std::string & conn)
   {
       std::clog << "Attempting to open the connection "<< std::endl ;
   }

   ~SqlServer()
   {
        std::clog << "SqlServer:Database object destroyed "<< std::endl ;
   }
} ;
int main()
{
   Database &ref = SqlServer();
   ref.Open("uid=user;pwd=default");
   return 0 ;
}
Run Code Online (Sandbox Code Playgroud)

产量

数据库对象已创建

试图打开连接

SqlServer:数据库对象被销毁//为什么这个被调用为析构函数在数据库中不是虚拟的

数据库对象已销毁

注意:如果我用pref替换ref,那么一切正常,即sqlserver析构函数不会被调用.

Kar*_*k T 5

这是const涉及临时参考时的特殊情况.临时的析构函数是正确调用的,而不是引用的析构函数,因为毕竟临时的生命周期只是扩展了.


类似于Andrei Alexandrescu在他的守门员中使用的技巧.他使用了const一个临时的引用.

根据C++标准,使用临时值初始化的引用使该临时值在引用本身的生命周期中存活.

临时变量与引用一样长 - 当它被销毁时,会调用正确的析构函数.

来自Generic:改变您编写异常安全代码的方式 - 永远


还解决了为什么派生类的析构函数在对基类的const引用上调用?