0

Pointで継承する基本クラスがありPoint3Dます。ただし、何らかの理由でクラスPointは常にPoint3D操作addのために戻る必要があるため、インクルードに含めます。

これは私のクラス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

私のクラスでは、最初に呼び出されるタイミングPoint3Dの定義にまだ遭遇していないことを知っているので(ヘッダーに含まれているため)、定義してから、使用する部分を定義します。PointPoint3DPointclass Point;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

ただし、これは機能していません。コンパイルすると、次のエラーが発生します。

./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.

ここでの質問は#include "Point.hpp"、私のPoint3D宣言からインクルードを削除することです。ただし、そうすることで同じ結果が得られ、ヘッダーガードは基本的に同じことを達成すると思います。

私はclangでコンパイルしています。

4

1 に答える 1

8

不完全な型から継承することはできません。次のようにコードを構造化する必要があります。

class Point3D;

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

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

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

関数の戻り型が不完全である可能性があるため、クラス定義はPointこのように機能します。

それをヘッダーファイルとソースファイルに分割する方法を理解できると思います。(たとえば、最初の2つの部分はに入ることができPoint.hpp、3番目の部分Point3D.hppにはインクルードが含まれPoint.hpp、最後の実装にはインクルードとPoint.cppが含まれる可能性がPoint.hppありPoint3D.hppます。)

于 2012-11-27T22:52:47.783 に答える