'&'之前的预期构造函数,析构函数或类型转换令牌错误

时间:2011-01-07 18:45:24

标签: c++ casting subtype

我的档案:

cpu_add.h

#ifndef CPU_ADD_H
#define CPU_ADD_H

double add_double_double(double a, double b) {return (a+b);}
double add_int_double(int a, double b) {return ((double)(a)+b);}
int   add_int_int(int a, int b) {return (a+b);}

#endif

我只允许使用上述功能。不能在我自己的代码中使用运算符'+'。

poly_subtype.h

#ifndef POLY_SUBTYPE_H
#define POLY_SUBTYPE_H
#include <iostream>
#include "q3.h"
#include "cpu_add.h"
using std::cout;
using std::endl;

//Deriving classes definition
class IntClass;
class DoubleClass;

//The Virtual Number Class. IntClass and FloatClass will derive from this class.
class Number {
    public:
        //return a Number object that's the results of x+this, when x is DoubleClass
        virtual Number& addDouble(DoubleClass& x) = 0;

        //return a Number object that's the results of x+this, when x is IntClass
        virtual Number& addInt(IntClass& x) = 0;

        //return a Number object that's the results of x+this, when x is either
        //IntClass or DoubleClass
        virtual Number& operator+(Number& x) = 0;

        //Print the number stored in the object
        virtual void print_number() = 0;        
};

class IntClass : public Number {
    private:
        int my_number;
    public:
        //Constructor
        IntClass(int n):my_number(n) {}

        //returns the number stored in the object
        int get_number()  {return my_number;}

        //print the number stored in the object
        void print_number() {cout << my_number << endl;}

        //return a DoubleClass object that's the result of x+this
        Number& addDouble(DoubleClass& x);

        //return an IntClass object that's the result of x+this
        Number& addInt(IntClass& x);

        //return a Number object that's the result of x+this.
        //The actual class of the returned object depends on x.
        //If x is IntClass, then the result if IntClass.
        //If x is DoubleClass, then the results is DoubleClass.
        Number& operator+(Number& x);
};

class DoubleClass : public Number {
    private:
        double my_number;
    public:
        //Constructor
        DoubleClass(double n):my_number(n) {}

        //returns the number stored in the object
        double get_number()  {return my_number;}

        //Print the number stored in the object
        void print_number() {cout << my_number << endl;}

        //return a DoubleClass object that's the result of x+this
        Number& addDouble(DoubleClass& x);

        //return a DoubleClass object that's the result of x+this
        Number& addInt(IntClass& x);

        //return a DoubleClass object that's the result of x+this.
        //This should work if x is either IntClass or DoubleClass
        Number& operator+( Number& x);
};

#endif

我需要实现下一个功能:

Number& IntClass::addInt(IntClass& x);
Number& IntClass::addDouble(DoubleClass& x);
Number& IntClass::operator+(Number& x);
Number& DoubleClass::addInt(IntClass& x);
Number& DoubleClass::addDouble(DoubleClass& x);
Number& DoubleClass::operator+(Number& x);

所以例如在我的q3.h中我写道:

#ifndef Q3_H_
#define Q3_H_

#include "cpu_add.h"
#include "poly_subtype.h"

Number& IntClass::addInt(IntClass& x){
    IntClass num(add_int_int(my_number, x.get_number()));
    return num;
}
#endif /* Q3_H_ */

我得到了下一个错误:

expected constructor, destructor, or type conversion before '&' token   q3.h    ‪/pl5‬  line 48 C/C++ Problem

这是什么意思?

感谢。

4 个答案:

答案 0 :(得分:2)

poly_subtype.h包含q3.h,q3.h包含poly_subtype.h。理论上这是允许的,因为你的多重包含警卫;但我认为这不是一个好主意: - )

答案 1 :(得分:1)

这是因为您将所有代码放在标题中(可能是以Java方式思考?)。

当您加入poly_subtype.h时,它会包含q3.h,然后包含poly_subtype.h以尝试定义各种类。由于你的包含警卫,第二个包括没有效果。然后,当编译器尝试编译q3.h时,它不知道Number类是什么,并生成该错误。

对此的修复是将方法实现放入仅编译一次的源文件中。它将防止嵌套的包含问题。或者,我无法理解为什么poly_subtype.h需要包含q3.h。如果删除它,则可能会修复它。

另外,作为旁注,IntClass::addInt通过引用返回本地,虽然它可能看似有效,但绝对不正确。你应该改为return *this;这是被修改的实际对象(我相信 - 从你的小样本中很难说出来。)

答案 2 :(得分:1)

因为你有循环依赖:

Sya你有这个文件:x.cpp

X.cpp

 #include "poly_subtype.h"

现在继承看起来像这样:

x.cpp
    // ---Included from x.cpp
    "poly_subtype.h"
        // ---Included from poly_subtype.h
        <iostream>               // OK
        "q3.h"
            // ---Included from q3.h
            "cpu_add.h"          // OK
            "poly_subtype.h"     // FAIL. poly_subtype.h guards kick in here.
                                 //       So no classes are defined.

                // DOUBLE FAIL
                // The class did not kick in becuase we failed to load the header file
                //
                // At this point IntClass has not been defined.
                Number& IntClass::addInt(IntClass& x){
                    IntClass num(add_int_int(my_number, x.get_number()));
                    return num;
                }
            // EXIT ---Included from q3.h

        "cpu_add.h"              // Already done. No Problem.

         class IntClass   // OOOPS. Whay to late.
                          //        declared after we need them

        // EXIT ---Included from poly_subtype.h
    // EXIT ---Included from x.cpp

简单的解决方案。
只在头文件中放置声明。将所有实现保留在cpp文件中。不要担心你认为你错过的所有内联优化,它仍然会发生在现代编译器中(如果编译器希望它发生它将会发生)。

在头文件中,forward声明您使用的任何类型只是引用或指针。只有#include一个文件,如果你从它作为基础派生,或者你有一个类的成员变量。这应该打破所有循环依赖。

为简单起见,每个头文件一个类(在合理范围内,如果它们都非常相似(使用最佳判断),则可以捆绑类组。)

答案 3 :(得分:0)

在.h文件中编写所有代码真是。 (当然有exeptions,但不适合新手).h文件是标题。 .cpp是您编写函数实现的实现文件。

并且像TonyK所说的那样:你通常包含文件会导致混乱。