问题标签 [virtual-destructor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1683 浏览

c++ - 将基类构造为抛出异常对象

直觉告诉我抛出的类型越简单越好。抛出一个 int 比抛出一个指针更好,抛出一个结构比抛出一个类更好。在这种情况下,尽管有必要抛出一个带有动态分配成员的几乎完整的类。在堆中分配内存很方便,因为缓冲区可能会变得很长并且复制很昂贵;它不需要方法,因为它充当其他对象的控制/参数结构,但是在堆中构建它以抛出指向结构的指针和使用析构函数来清理内存都很方便。越简单越好,那么析构函数应该是虚拟的吗?省略 vtable或vtables完全不影响异常传递会更好吗?

从此结构派生类作为基类的优点是添加更多数据,而不是多态方法。指针可能会在异常点前几层被捕获并在模块之间传递,因此对象应尽可能干净,并尽可能降低复合错误的风险。

0 投票
3 回答
2352 浏览

c++ - C++ 虚拟析构函数

如果我有一个基类和一个派生类,并且我在父虚拟中删除了析构函数,但实例化了一个子类类型的对象,那么在销毁时它会调用父析构函数吗(因为是虚拟的)?如果我还在派生类中声明了一个析构函数,它会同时调用两个析构函数(基类和派生类)。提前致谢 :-)。

我的问题的第二部分是关于第一部分。为什么基类析构函数需要声明为virtual。不要构造函数在层次结构中循环。他们不共享相同的名字,那么哪里需要它?它不应该对析构函数起作用吗,或者默认情况下只有一个被调用?另外通过后期绑定是否能够检测到所有的类和对象是由什么组成的?

编辑:我的问题不仅仅是关于虚拟析构函数,而是为什么它需要被声明为虚拟的,因为它们都应该被默认调用。

0 投票
4 回答
21940 浏览

c++ - 类具有虚函数和可访问的非虚析构函数

我有两节课:

但是使用 g++ 我得到错误:

我不知道这个错误是什么......我在博客的某个地方读到这是一个编译器警告。我该如何解决这个问题?

0 投票
5 回答
861 浏览

c++ - 使用向上转换时的虚拟析构函数

每个人都说,当至少一个类方法是虚拟的时,析构函数应该是虚拟的。
我的问题是,在使用向上转换时说析构函数应该是虚拟的不是正确的吗?

我在这段代码中没有任何虚函数,但是如果我不将我的基本析构函数设为虚拟,它就不会调用 B 析构函数。是的,我知道如果我没有虚拟功能,使用 ucpasting 毫无意义。

谢谢你。

0 投票
3 回答
3685 浏览

c++ - 直接调用(虚拟)析构函数是否有效?

这个答案中,Ryan 直接调用了虚拟析构函数。我已经在 VS2010 中测试了代码,它正确地调用了所有的析构函数(用日志语句测试)。这样做真的有效吗?这种方法有哪些问题、缺陷甚至优点?

我只能将其视为一种真正强制重置实际类型的方法,即使它们不覆盖虚reset函数,因为它们至少必须在其析构函数中进行清理。

另外,调用析构函数究竟会带来什么样的副作用?在这样的析构函数调用之后使用对象是未定义的行为吗?如果立即通过new (this) MyClass();调用重新初始化它会怎样?

0 投票
2 回答
1905 浏览

c++ - 当派生类的析构函数是虚拟的而基类的 dtor 不是时代码崩溃

我在 gcc 4.4.5 上尝试了以下代码。

如果成员“数据”不存在,则代码可以正常执行,但如果存在,则会崩溃。当派生类的 dtor 不是虚拟的时,它也不会崩溃。

我知道在这两种情况下,行为都是未定义的,如 C++03 (5.3.5 / 3)中所列,但仍然有人可以向我提供一些解释,为什么它在后一种情况下会崩溃?

是的,我知道 UB 意味着任何事情都可能发生,但我仍然想知道特定于实现的细节。

0 投票
2 回答
6432 浏览

c++ - 纯虚析构函数应该在哪里声明?

编辑:显然这个问题的表述不够清楚。我遇到的问题是,当在标头中定义析构函数时,它会被添加到多个 .obj 文件中,并且链接器会抱怨。实际的问题是:

当我将析构函数添加到 DLL 项目中的 CPP 文件并使用具有动态加载和接口头文件的 dll 时,是否仍会调用基本析构函数以防止内存泄漏?

我正在使用 MSVC 10.0 并且有一个实现接口的 DLL 项目。接口是一个抽象(纯虚拟)基类。这个想法是标题与库的动态加载一起使用。因此,我使用了纯虚析构函数来确保调用基类中的析构函数。这是解释这一点的示例代码:

以及主要的实现头

一些帮助类

现在的问题是链接器生成一个错误,告诉我析构函数: ISplitter::~ISplitter(void) 已被多次声明,系统将无法构建。错误:

解决此问题的正确方法是什么?我已将析构函数放在 ISplitter.cpp 中,但我担心如果我动态加载库并将基类向上转换为 ISplitter,这可能不起作用。

0 投票
3 回答
4148 浏览

c++ - 为什么析构函数默认不是虚拟的[C++]

为什么 C++ 默认情况下不为至少有一个其他虚函数的类使析构函数变为虚拟? 在这种情况下,添加虚拟析构函数不会花费我任何成本,而且没有(几乎?)总是一个错误。C++0x 会解决这个问题吗?

0 投票
1 回答
1229 浏览

c++ - 如果您始终将其存储在 shared_ptr 中,您的接口是否需要虚拟析构函数?

由于boost::/std::shared_ptr具有类型擦除其删除器的优势,因此您可以做一些不错的事情,例如

由于保存了正确的删除器,这将正确删除所有指针。

如果你确保你的接口的每个实现总是用shared_ptr<Interface>(or make_shared<Interface>) 创建,你真的需要一个virtual析构函数吗?无论如何我都会声明它virtual,但我只想知道,因为shared_ptr将始终删除它初始化的类型(除非给出另一个自定义删除器)。

0 投票
1 回答
182 浏览

inheritance - 在非 Q 的构造函数和析构函数中取消对 vtable 的引用

我有一个基类 GameObject,它目前是 Camera 和 SolidObject 的父类。SolidObject 父级 Player 和 GameMap。出于某种原因,我只在 GameMap 的构造函数和析构函数中获得了对 vtable 的未定义引用。这是代码(我不包括相机或播放器)。注意:GameObject 和 SolidObject 在 World.h 中,因为它们很小并且需要连接。我只会包含与这些类和 GameMap 相关的内容。

我切换了继承,所以 GameMap 继承自 GameObject 而不是 SolidObject,但它仍然会导致相同的错误。

世界.h

世界.cpp

游戏地图.h

游戏地图.cpp