【问题标题】:auto_ptr and forward declarationsauto_ptr 和前向声明
【发布时间】:2016-07-27 08:13:41
【问题描述】:

我知道:

#include <memory>
class A;
class B 
{ 
  public:
      B(A* a) : a_(a) {}
  private:
      std::auto_ptr<A> a_;
};

与未定义的行为发生冲突,除非您的 B::~B() 定义越界;

在某一时刻,gcc 曾经这样说:

blah/auto_ptr.h: 在析构函数'std::auto_ptr<_tp>::~auto_ptr() [with _Tp = B]': test.hh:6: 从这里实例化

blah/auto_ptr.h:173:注意:无论是析构函数还是特定于类的操作符 delete 都不会被调用,即使它们是在定义类时声明的。

我们可以检测到这一点并在任何不好的事情发生之前修复代码。有时这停止发生。是否有任何编译器选项可以打开它(-Wall -Wextra -Wpedantic 似乎没有削减它)

注意:由于各种原因,不能迁移到 C++11 和 unique_ptr,据我阅读,unique_ptr 也存在同样的问题。

【问题讨论】:

  • std::auto_ptr 的设计存在根本缺陷。即使您无法迁移到 C++11 或更高版本,您也应该考虑放弃 auto_ptr 以支持替代解决方案。它是如此的有缺陷,以至于该类型将从 C++17 的标准库中完全删除。

标签: c++ gcc-warning


【解决方案1】:

unique_ptr没有这个问题,因为你在构造unique_ptr对象的时候绑定了deletor:

  struct A;
  struct B {
    std::unique_ptr<A> p;
  };
  struct A {
    ~A() {
    }
  };
  {
    B b;
    b.p = std::unique_ptr<A>(new A()); // here is you bind default_deletor of already completed type
  }

因此,为 B 类生成的析构函数正确地销毁了 p 成员。

更新:

如果你不打算迁移到 C++11,你可以使用 unique_ptr 智能指针之类的东西来消除 auto_ptr 的问题。

【讨论】:

  • 如问题所述,使用 unique_ptr 不是选项
  • @TomTanner 但“据我所知,unique_ptr 存在同样的问题”不是真的
  • 这不是不能迁移到 C++11 的原因
  • @TomTanner 没有人强迫你,因为你自己决定应该做什么
【解决方案2】:

其实……

libstdc++ 使std::unique_ptr 的实例化成为编译器错误:

#include <memory>
class A;
class B 
{ 
  public:
      B(A* a) : a_(a) {}
  private:
      std::unique_ptr<A> a_;
};

Live on Coliru

In file included from /usr/local/include/c++/6.1.0/memory:81:0,
                 from main.cpp:1:
/usr/local/include/c++/6.1.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = A]':
/usr/local/include/c++/6.1.0/bits/unique_ptr.h:236:17:   required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A; _Dp = std::default_delete<A>]'
main.cpp:6:21:   required from here
/usr/local/include/c++/6.1.0/bits/unique_ptr.h:74:22: error: invalid application of 'sizeof' to incomplete type 'A'
  static_assert(sizeof(_Tp)>0,

虽然这种检查似乎不需要,但实现起来很简单,所以C++标准库的实现应该会有这样的检查。

【讨论】:

  • @TomTanner 这是对“unique_ptr 存在相同问题”的回应。如果这会阻止您迁移,那么您会发现这不是问题。
  • 这不是阻止我迁移的原因。无论如何,我的问题是关于 auto_ptr 在没有警告的情况下编译的事实
猜你喜欢
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多