【问题标题】:Deletion of pointer to incomplete type 'Point'; no destructor called删除指向不完整类型'Point'的指针;没有调用析构函数
【发布时间】:2013-03-27 04:45:20
【问题描述】:

我有 2 个文件:

Point.h:

class Point {
    int x;
    int y;
    char* name;
   public:
     Point() { name = new char[5]; }
    ~Point() { delete[] name; }
};

和:Line.h:

class Point;
class Line {
    Point* p;
  public:
    Line() {
      p = new Point[2];
      ....
      ...
    }
    ~Line() {
       delete[] p;
    }
};

但是当我编译时,我得到了下一个错误:

deletion of pointer to incomplete type 'Point'; no destructor called

任何帮助表示赞赏!

【问题讨论】:

  • 注意:std::string name; 和 std::array<Point, 2>。摆脱像这样动态分配内存时必须处理的烦人的额外功能。
  • 请参阅此处以使此警告被视为错误...应该是...:stackoverflow.com/questions/4750880/… (#pragma warning (error: 4150))

标签: c++ class pointers destructor


【解决方案1】:

您需要将#include "Point.h" 添加到您的文件Line.h 中。您只能构造和删除 完整 类型。

或者,从Line.h 中删除成员函数定义,并将它们放在单独的文件Line.cpp 中,并在那个 文件中包含Point.h 和Line.h。这是一种典型的依赖减少技术,可以使代码更快地编译,尽管可能会失去某些内联机会。

【讨论】:

  • @vonbrand - 良好的风格决定了包括它。标头应该可以自己编译;这样一来,神秘错误就会减少。
  • @vonbrand - 我职业生涯的大部分时间都在编写和维护库并提供技术支持,我强烈反对。告诉用户在使用您的标头之前必须包含六个必备标头是一件令人头疼的事情,并且对实施者或用户没有任何好处。
  • @vonbrand:老实说,在阅读了您的评论后,我无法想象您已经用 C 或 C++ 进行过任何认真的开发。这太疯狂了;当然,您通常会在标题中包含文件。在现实世界的代码中根本没有办法绕过它,也没有任何问题。如果您正在编写具有脆弱依赖关系的标头,那么 that 就是问题所在。
  • 那么呃...为什么我的代码在 C++ 中编译和运行,而这只是一个警告?默认行为应该是错误...
  • 看起来我可以用这个破解它以使其正常运行...:stackoverflow.com/questions/4750880/… (#pragma warning (error: 4150))
【解决方案2】:

您已经前向声明了Point,这适用于声明指针或引用,但不适用于编译器需要知道前向声明类的定义的任何其他内容。

如果您需要头文件中的前向声明(是吗?如果不需要,只需 Line.h 中的 #include "Point.h" )然后在 #includes Point.h 的实现文件中实现您的 Line 函数。

【讨论】:

    【解决方案3】:

    为了扩展其他人给出的建议——一条线总是由两个端点定义的。将这些点定义为堆分配内存没有多大意义。为什么不让这两个点成为Line 类的常规成员呢?这将节省内存、提高性能并产生更简洁的代码。不过,您必须包含 "Point.h" 才能使其正常工作。

    【讨论】:

    • 你是对的,但是这种简单的代码是很多人开始学习动态内存的地方
    猜你喜欢
    • 2011-08-02
    • 2010-10-15
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2018-02-06
    • 2020-06-12
    相关资源
    最近更新 更多