13

I have 2 files:

Point.h:

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

and: Line.h:

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

but when I compile, I got the next error:

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

any help appreciated!

vonbrand
  • 11,412
  • 8
  • 32
  • 52
Alon Shmiel
  • 6,753
  • 23
  • 90
  • 138
  • 4
    Note: `std::string name;` and `std::array`. Get rid of the icky extra functions you have to take care of when dynamically allocating memory like that. – chris Apr 04 '13 at 22:11
  • 1
    Please see here to make this warning be treated as an error... like it should be...: https://stackoverflow.com/questions/4750880/can-i-treat-a-specific-warning-as-an-error (`#pragma warning (error: 4150)`) – Andrew May 23 '18 at 02:16

4 Answers4

18

You need to add #include "Point.h" into your file Line.h. You can only construct and delete complete types.

Alterntively, remove the member function definitions from Line.h, and put them in a separate file Line.cpp, and include Point.h and Line.h in that file. This is a typical dependency reduction technique which makes code faster to compile, although at a potential loss of certain inlining opportunities.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 3
    @vonbrand - good style dictates including it. Headers should be compilable on their own; there are fewer mysterious errors that way. – Pete Becker Apr 04 '13 at 23:25
  • 8
    @vonbrand - having spent most of my career writing and maintaining libraries and providing technical support, I strongly disagree. Telling users that they have to include half a dozen prerequisite headers before they can use your header is a headache, and provides no benefit to the implementor or to the user. – Pete Becker Apr 04 '13 at 23:55
  • 1
    @vonbrand: Honestly, after reading your comment, I can't imagine you have done any serious development in C or C++. That's just insane; of course you will often include files in a header. There is simply no way around it in real world code, and there's nothing wrong with it either. If you're writing headers that have fragile dependencies then *that* is the problem. – Ed S. Apr 05 '13 at 00:19
  • So uhh... Why the heck does my code compile and run in c++ with this just being a warning? The default behavior should be to error... – Andrew May 23 '18 at 02:12
  • Looks like I can hack it into proper operation with this...: https://stackoverflow.com/questions/4750880/can-i-treat-a-specific-warning-as-an-error (`#pragma warning (error: 4150)`) – Andrew May 23 '18 at 02:16
5

You have forward declared Point, which is fine for declaring a pointer or reference, but not fine for anything else in which the compiler would need to know the definition of the forward declared class.

If you need the forward declaration in the header file (do you? If not, just #include "Point.h" in Line.h ) then implement your Line functions in an implementation file which #includes Point.h.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
0

To expand a bit on a suggestion other people gave -- a line is always defined by two end points. There isn't much point in defining these points as a heap-allocated memory. Why not make the two points regular members of the Line class? This will save memory, improve performace and lead to a cleaner code as well. You'll have to include "Point.h" for this to work, though.

Jan Kundrát
  • 3,700
  • 1
  • 18
  • 29
0

forward declaration sample with a namespace.

// my header.h
namespace Poco {
    class TextConverter;
}
Dmitry Ivanov
  • 508
  • 7
  • 9