关于c ++:什么时候不希望派生类的解构器执行?

When would one NOT want a derived class's deconstructor to execute?

考虑下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

class Base
{
public:
  Base() { std::wcout << L"Base cons" << std::endl; }
  ~Base() { std::wcout << L"Base des" << std::endl; }
};

class Derived : public Base
{
public:
  Derived() { std::wcout << L"Derived cons" << std::endl; }
  ~Derived() { std::wcout << L"Derived des" << std::endl; }
};

int main()
{
  Base * derived = new Derived;
  std::wcout << L"Deleting..." << std::endl;
  delete derived; // Base::~Base() is not virtual so only Base::~Base() is called

  return 0;
}

// Ouput
// Base cons
// Derived cons
// Deleting...
// Base des

由于基础:基础:~()是不是虚拟的,当对象被删除,只有"衍生"的基础:基础:~()将被执行。是不是内存泄漏,如果我们don’t call()来源:来源:~,太?当然,这是很容易地被标记的remedied基础:基础:~()deconstructor什么是虚拟的,但这一场景将要毁灭的基础类和衍生类衍生的不是吗?

(这是我的理解是"一次调用基类的析构函数调用的源对象,不再是在可用的状态)

我设计了一种实现C + +效率"是只支付你所需要的",所以我真的很想了解为什么declaring源性类不需要虚拟基类deconstructor(避免内存泄漏本身没有清洗上的衍生类)

谢谢你在前进的见解。


执行delete derived不一定是内存泄漏,其中derivedBase*类型。因为当Base没有虚拟析构函数时,这是未定义的行为。任何事或任何事都可能发生,包括你期望发生的事。

请注意,这种情况可能发生在unique_ptr上,其值是从unique_ptr复制的。所以这是一种特殊的智能指针不那么智能的情况。值得牢记。

但是,使用shared_ptr是安全的,因为使用shared_ptr时,原始指针保存在控制块中并用于删除。

关于标题中的问题,

” When would one NOT want a derived class's deconstructor to execute?

&只有当一个人根本不想破坏对象的时候。

我能想到的唯一例子可能是一个记录器对象。

关于问题文本末尾的问题,

” I'm really just looking to understand why declaring a derived class does NOT require a virtual base class deconstructor

&这是另一个问题。

作为一个具体的例子,使用微软的COM技术,每个COM类继承的IUnknown接口没有虚拟析构函数。它不需要这样做,因为当引用计数变为零时,任何COM对象都会自毁。自毁代码可以访问最派生的类。


唯一不希望使用析构函数虚拟的场景是不需要虚拟析构函数的场景。基本上,一个自制的预言。

如果不可能使用指向超类的指针来销毁对象,并且该对象没有其他虚拟方法,那么不声明虚拟析构函数将生成一个更高效的代码。


如果派生类不添加任何内存(例如,只更改行为),则可以这样保存一些CPU周期(因为没有任何"泄漏")。

可能不是一个好主意-让编译器进行这样的优化。