【问题标题】:C++: Destructor not called with embedded templateC ++:未使用嵌入式模板调用析构函数
【发布时间】:2015-06-04 15:48:45
【问题描述】:

简短:删除模板化指针不会调用析构函数。

include 解决了这个问题。为什么?

我刚刚遇到了一个我无法解释的情况。我试图在这里打破更复杂的情况。

文件 R.cpp

class R {
      Owner<Problem> m_o;
      void cleanUp() { m_o.clear(); }
     }

文件所有者.cpp

struct DeleteFunctor {
  template< class TPtr > void operator()(TPtr* ptr) {  delete ptr; }
};

template< class T >
class Owner { 
std::vector<T*> m_objects; 
// here add and other stuff
void clear() {
  std::for_each( m_objects.begin(), m_objects.end(), DeleteFunctor() );
  m_objects.clear();
}

我现在有一个实用程序类,它在堆上创建新的问题对象并将它们直接插入 m_o。我知道导出对内部类型的引用是不好的风格,但这不是重点。

如果我调用 cleanUp(),我可以将其追溯到 Functor 中的调用 delete ptr,其中 ptr 具有正确的问题类型。但是没有调用问题析构函数!!

但是,在文件 R.cpp 中包含问题标头可以解决问题。编译器没有抱怨。这是编译器的错误吗?

系统: g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2

【问题讨论】:

  • 为什么不std::vector&lt;std::unique_ptr&lt;T&gt;&gt;
  • 在这种情况下,T 可能是什么?
  • 添加或删除这样的代码行,然后看到不同的行为表明您有内存损坏错误。您真正要做的只是更改可执行映像,将错误移动到程序的不同部分。所以你真的没有解决问题。
  • 你在R::cleanUp()而不是R::~R()中调用m_o.clear()

标签: c++ templates destructor


【解决方案1】:

来自标准(n3242 草案)§5.3.5/5:

如果要删除的对象在删除点具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为未定义。

在这种情况下,如果您不包含定义 TProblem 的标头,那么您将删除一个不完整类型的对象。如果该类型不满足该子句中的要求,则删除行为未定义。

这是编译器错误吗?

不,编译器不需要警告未定义的行为。

您可能需要TOwner 才能完成。如果T 不完整,像static_assert(sizeof(T) &gt; 0) 这样的东西应该无法编译。

如果你不能依赖当前的标准,你可以使用boost::checked_deleter 作为你的删除函子。它在 c++11 之前进行完整性检查。如果您出于某种原因不想包含 boost 标头,那么只需重新实现它。这是检查完整性的代码。

// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;

请注意,您实际上是在部分重新实现 std::vector&lt;std::unique_ptr&lt;T&gt;&gt; 如果您可以使用 c++11,我建议改用它。

【讨论】:

  • 这出现在标准的什么地方?可以编辑吗?
  • 当然这是有道理的——如果你给我看一段记忆并说“删除这里的 foobar”,除非我知道 foobar 有多大谁知道我在做什么。跨度>
  • 非常感谢您指出这一点。不幸的是,C++11 不是一个选项 :( 我如何避免在这种情况下运行?这可能是一个复杂项目的调试噩梦。
  • @user4575239 如果您的模板不执行任何其他需要类型完整的操作(例如构造等),那么据我所知,您最好的选择是使用技巧测试完整性。 Boost 有 check_deleter 使用这种技巧。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2018-02-03
  • 2016-06-07
  • 2017-04-28
  • 1970-01-01
相关资源
最近更新 更多