AntoineG
AntoineG

Reputation: 1247

Base class has incomplete type

I have a base class Point from which I inherit in Point3D. However, for some reason class Point must always return Point3D for the operation add, so I include it in my includes.

This is my class Point:

#ifndef POINT_H
#define POINT_H

#include "Point3D.hpp"

class Point{

  public:
    Point(double, double, double);

    void print() const;
    Point3D add( const Point& );

  protected:
    double mX;
    double mY;
    double mZ;

};

#endif

In my class Point3D, I know I will not yet have encountered the definition of Point when I will first be called (because Point3D is included in the Point header), so I define class Point;, then I define the parts I will use of Point:

#ifndef POINT3D_H
#define POINT3D_H

#include <iostream>
#include "Point.hpp"  // leads to the same error if ommitted

class Point;    

class Point3D : public Point {

  public:
        Point3D(double, double, double);
        void print() const ;
        Point3D add(const Point&);
};

#endif

However, this is not working. When I compile it, it gives me the following error:

./tmp/Point3D.hpp:9:24: error: base class has incomplete type
class Point3D : public Point {
                ~~~~~~~^~~~~
./tmp/Point3D.hpp:7:7: note: forward declaration of 'Point'
class Point;
      ^
1 error generated.

The question here would say to remove the include #include "Point.hpp" from my Point3D declaration. However, doing so leads to the same result, and I think the header-guards would basically accomplish the same thing.

I'm compiling with clang.

Upvotes: 1

Views: 11569

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477040

You can't inherit from an incomplete type. You need to structure your code as follows:

class Point3D;

class Point
{
    // ...
    Point3D add(const Point &);
    // ...
};

class Point3D: public Point
{
    // ...
};

Point3D Point::add(const Point &)
{
    // implementation
}

Function return types may be incomplete, which is why your class definition of Point works like this.

I trust you can figure out how to split that across header and source files. (For example, the first two parts can go in Point.hpp, the third in Point3D.hpp which includes Point.hpp, and the final implementation can go in Point.cpp which includes Point.hpp and Point3D.hpp.)

Upvotes: 9

Related Questions