为什么在调用隐式类型转换构造函数后直接使用析构函数?

时间:2012-12-20 11:51:58

标签: c++ gcc implicit-conversion

提供以下功能:

osal_allocator* SharedMemoryManager::allocator();I  

其中osal_allocator是'c'结构,包含函数指针。

提供以下构造函数的包装类:

Allocator::Allocator( osal_allocator* );

一个函数进行以下调用:

001 SomeFunc( SharedMemoryManager* shm )
002 {
003    Allocator myAllocator = shm.allocator();
004
005    myAllocator.doSomething();
006
007    // stuff
008 }

代码以SIG SEGV失败。原因是在003行上myAllocator的析构函数在调用构造函数后立即被调用。这意味着myAllocator005行无效,因为它已被销毁。

(注意:默认构造函数未被调用,也没有任何赋值运算符)。

如果行003更改为:

003    Allocator myAllocator( shm.allocator );

该函数按预期工作,myAllocators的析构函数在超出范围之前不会被调用。

不幸的是,我无法用一个简单的例子重现这个问题。

我正在使用:

g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)

使用以下选项:

c++ -MD -D__LINUX__  -g -ansi -Wall -Wextra -Wformat -Wno-format-security -Woverloaded-virtual -Iinc

为什么编译器会为第一个示例

生成析构函数调用

2 个答案:

答案 0 :(得分:1)

Allocator myAllocator = shm.allocator();是复制初始化,涉及转换构造函数(来自osal_allocator*)和复制构造函数(来自临时Allocator)的调用。被调用的析构函数是临时Allocator对象的析构函数。

崩溃可能是由于Allocator中缺少复制构造函数或执行不当的复制构造函数。

这可以通过将初始化更改为

的说法来支持
Allocator myAllocator( shm.allocator );

有效 - 这是因为没有涉及复制 - 直接调用转换构造函数,不创建临时对象。

Read up on "the rule of three".

基本上,如果一个类需要析构函数,复制构造函数或复制赋值运算符(通常是类管理资源时的情况),则需要所有这三个

答案 1 :(得分:1)

使用此行

Allocator myAllocator = shm.allocator();

您正在执行以下操作:

  1. 构建新的Allocator临时对象
  2. 调用Allocator的复制构造函数,其中rhs是临时的
  3. 销毁在第1点创建的临时对象
  4. 您可能会考虑两种可能的操作,这可能导致SIG SEV:复制构造函数和析构函数。