gpt4 book ai didi

c++ - 为什么在对基类的 const 引用上调用派生类的析构函数?

转载 作者:可可西里 更新时间:2023-11-01 17:14:19 25 4
gpt4 key购买 nike

GMan's answer hererestore_base 类的析构函数不是 virtual,所以我一直想知道它究竟是如何工作的。通常您希望 restorer_base 的析构函数仅在对象超出范围后执行,但派生的 restorer_holder 析构函数似乎真的被调用了。有谁愿意赐教吗?

最佳答案

需要虚拟析构函数的标准情况是

void foo()
{
scoped_ptr<Base> obj = factory_returns_a_Derived();

// ... use 'obj' here ...
}

而您的标准情况是

void foo()
{
Derived obj;

// ... use 'obj' here ...
}

GMan 的代码做了一些更棘手的事情,结果等同于第二种情况:

void foo()
{
Base& obj = Derived();

// ... use 'obj' here ...
}

obj 是一个简单的引用;通常,它根本不会触发析构函数。但它是从一个匿名临时对象初始化的,该对象的静态类型(编译器已知)是 Derived。当该对象 的生命周期结束时,编译器将调用Derived 析构函数。通常情况下,匿名临时对象会在创建它的表达式结束时结束,但对于初始化引用的临时对象来说有一种特殊情况:它们一直存在到引用本身结束,这里是作用域的结束.所以你得到伪 scoped_ptr 行为,你不需要虚拟析构函数。

编辑:因为这已经出现了两次:引用不必必须是const才能应用此特殊规则。 C+98 [class.temporary]/5:

The second context [in which a temporary object is not destroyed at the end of the full-expression] is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference ...

强调我的。此语言中没有提及 const,因此引用不必是 const

编辑 2: 标准中的其他规则禁止创建对非左值的临时对象的非常量引用。我怀疑至少有一些临时对象 左值,但我不确定。无论如何,这不会影响此规则。对临时对象的非 const 引用延长它们的生命周期在形式上仍然是正确的,即使没有严格符合 C++ 的程序可以创建这样的引用。这可能看起来很荒谬,但您应该从字面上和迂腐地阅读标准语。每个词都很重要,每个不存在的词都很重要。

关于c++ - 为什么在对基类的 const 引用上调用派生类的析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4985800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com