简体   繁体   中英

Refering to subclasses in the superclass (C++)

I've got a problem with the implementation of my design. There is a superclass defining methods, which have subclasses of this superclass as return values. As you can see here:

#ifndef I_ATTITUDEDESCRIPTOR_H
#define I_ATTITUDEDESCRIPTOR_H

#include "cl_EulerAngles.h"
#include "cl_Quaternion.h"
#include "cl_RodriguesParameters.h"
#include "cl_RotationMatrix.h"
#include "cl_TransformationMatrix.h"

class i_AttitudeDescriptor {
    public:
        i_AttitudeDescriptor();
        virtual ~i_AttitudeDescriptor() = 0;

        virtual cl_EulerAngles* getEulerAngles(cl_EulerAngles* result) = 0;
        virtual cl_Quaternion* getQuaternion(cl_Quaternion* result) = 0;
        virtual cl_RodriguesParameters* getRodriguesParameters(cl_RodriguesParameters* result) = 0;
        virtual cl_RotationMatrix* getRotationMatrix(cl_RotationMatrix* result) = 0;
        virtual cl_TransformationMatrix* getTransformationMatrix(cl_TransformationMatrix* result) = 0;
    protected:
    private:
};

#endif // I_ATTITUDEDESCRIPTOR_H

One of the subclasses is for example given by:

#ifndef CL_EULERANGLES_H
#define CL_EULERANGLES_H

#include "i_AttitudeDescriptor.h"

#include "cl_Quaternion.h"
#include "cl_RodriguesParameters.h"
#include "cl_RotationMatrix.h"
#include "cl_TransformationMatrix.h"


class cl_EulerAngles : public i_AttitudeDescriptor
{
    public:
        cl_EulerAngles();
        ~cl_EulerAngles();

        cl_EulerAngles* getEulerAngles(cl_EulerAngles* result);
        cl_Quaternion* getQuaternion(cl_Quaternion* result);
        cl_RodriguesParameters* getRodriguesParameters(cl_RodriguesParameters* result);
        cl_RotationMatrix* getRotationMatrix(cl_RotationMatrix* result);
        cl_TransformationMatrix* getTransformationMatrix(cl_TransformationMatrix* result);
    protected:
    private:
};

#endif // CL_EULERANGLES_H

The functions are implemented in the cl_EulerAngles.cpp file. Now I got the problem, that I get a compiler error like this:

i_AttitudeDescriptor.h|17|error C2143: syntax error : missing ';' before '*'|
i_AttitudeDescriptor.h|17|error C2433: 'i_AttitudeDescriptor::cl_EulerAngles': 'virtual' not permitted on data declarations|
i_AttitudeDescriptor.h|17|error C4430: missing type specifier - int assumed|
i_AttitudeDescriptor.h|17|error C2061: syntax error : identifier 'cl_EulerAngles'|
i_AttitudeDescriptor.h|17|error C4430: missing type specifier - int assumed|
i_AttitudeDescriptor.h|17|warning C4183: 'getEulerAngles': missing return type; assumed to be a member function returning 'int'|
i_AttitudeDescriptor.h|17|error C2253: "i_AttitudeDescriptor::getEulerAngles": pure specifier only applies to virtual function – specifier ignored|
||=== Build finished: 6 errors, 1 warnings (0 minutes, 0 seconds) ===|

I'm hoping someone out there can help me fixing this little problem. Thank you.

The compilation problem is because of the circular include directives. However, underneath the simple circular inclusion, there is a bigger design problem here. Base class is not supposed to know the subclasses.

Better solution: You should return a pointer to the Base class and use Polymorphism .

Not that good solution: If you really want to continue with your current design, you might consider not including the subclass headers, but forward declaring your subclasses in the base class header file. This will solve the circular inclusion.

I would recommend sticking with the first solution.

The problem here is circular includes; i_AttitudeDescriptor.h pulls in cl_EulerAngles.h , which pulls in i_AttitudeDescriptor.h . Once the include guards kick in, you end up missing declarations, which seems to be what the compiler is complaining about.

There are at least two solutions:

  1. Forward declare the various types that are used in i_AttitudeDescriptor.h instead of #include ing their header files. i_AttitudeDescriptor doesn't care about the details of those classes, just their names.

  2. Declare all those virtual functions in i_AttitudeDescriptor as returning pointers to i_AttitudeDescriptor rather than pointers to the specific types. You can still override them in derived classes with functions that return pointers to the derived types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM