我对接线员有疑问。通常,我知道使用运算符的基础知识。但是,当我想比较两个对象时,我的问题就开始了。我有2个不同的类声明文件okrag.h和prostokat.h。我想比较来自不同类的两个对象:

//okrag.h   -- circle class
#ifndef __OKRAG_H__
#define __OKRAG_H__
#include "figura.h"
#include "prostokat.h"

class COkrag: public CFigura
{
    protected:
    int m_iR;

    public:
        COkrag();
        COkrag(int x, int y, int r);
        ~COkrag();
        void ZmienR(int r);
        float PodajObwod();
        float PodajPole();
        int PodajR();
        void operator+(int r);
        friend void operator+(COkrag o, int x[2]);


        bool operator>(COkrag o2);

        friend bool operator>(COkrag o1, CProstokat o2);

        bool operator<(COkrag o2);
        bool operator>=(COkrag o2);
        bool operator<=(COkrag o2);
        friend ostream& operator << (ostream &wy, COkrag &O);

};
#endif



//prostokat.h
#ifndef __PROSTOKAT_H__
#define __PROSTOKAT_H__
#include "figura.h"
#include "okrag.h"

class CProstokat: public CFigura
{
    protected:
    int m_iSz, m_iWy;


    public:
        CProstokat();
        CProstokat(int x, int y, int szer, int wys);
        ~CProstokat();
        void ZmienSz(int x);
        void ZmienWy(int y);
        float PodajObwod();
        float PodajPole();
        void operator+(int a);
        friend void operator+(CProstokat p, int x[2]);

        bool operator>(CProstokat p2);
        bool operator<(CProstokat p2);
        bool operator>=(CProstokat p2);
        bool operator<=(CProstokat p2);


        friend ostream& operator << (ostream &wy, CProstokat &P);

};
#endif


我的问题是何时开始编译并找到此行:friend bool operator>(COkrag o1, CProstokat o2);

它说:Error 1 error C2061: syntax error : identifier 'CProstokat'

我不知道是什么原因。似乎它不知道对象CProstokat,但包含带有此类声明的头文件。

谁能告诉我怎么了?

编辑:
我已经更正了我的代码,这就是我得到的。我不知道为什么不能将const添加到bool operator>(CProstokat & p2);中,我希望它看起来像这样:

bool operator>(CProstokat & p2);

但是编译器说

Error 3 error C2662: 'CProstokat::PodajPole' : cannot convert 'this' pointer from 'const CProstokat' to 'CProstokat &'

现在,没有它就可以工作。这就是我得到的。

#ifndef __OKRAG_H__
#define __OKRAG_H__
#include "figura.h"


class CProstokat;

class COkrag: public CFigura
{
    protected:
    int m_iR;

    public:
        COkrag();
        COkrag(int x, int y, int r);
        ~COkrag();
        void ZmienR(int r);
        float PodajObwod();
        float PodajPole();
        int PodajR();
        void operator+(int r);
        friend void operator+(COkrag o, int x[2]);




        bool operator>(const CProstokat & p2); //I have changed it because now I can use 'this->'
        bool operator<(CProstokat & p2);
        bool operator>=(CProstokat & p2);
        bool operator<=(CProstokat & p2);

        bool operator>(COkrag o2);
        bool operator<(COkrag o2);
        bool operator>=(COkrag o2);
        bool operator<=(COkrag o2);
        friend ostream& operator << (ostream &wy, COkrag &O);

};
#endif


#ifndef __PROSTOKAT_H__
#define __PROSTOKAT_H__
#include "figura.h"


class COkrag;
class CProstokat: public CFigura
{
    protected:
    int m_iSz, m_iWy;


    public:
        CProstokat();
        CProstokat(int x, int y, int szer, int wys);
        ~CProstokat();
        void ZmienSz(int x);
        void ZmienWy(int y);
        float PodajObwod();
        float PodajPole();
        void operator+(int a);
        friend void operator+(CProstokat p, int x[2]);

        bool operator>(COkrag& o2);
        bool operator<(COkrag& o2);
        bool operator>=(COkrag& o2);
        bool operator<=(COkrag& o2);

        bool operator>(CProstokat p2);
        bool operator<(CProstokat p2);
        bool operator>=(CProstokat p2);
        bool operator<=(CProstokat p2);


        friend ostream& operator << (ostream &wy, CProstokat &P);

};
#endif


希望我能正确理解您的建议。感谢大家花时间在回答上。

最佳答案

问题是头文件相互包含。这将导致以下情况:

假设某些代码文件包含procostat.h。现在,在处理procostat.h时,预处理器将首先处理include保护,定义__PROKOSTAT_H__(边节点:包含双下划线的所有标识符均保留用于实现;请勿将其用于您自己的代码),然后包括figura.h ,然后查找并处理#include "okrag.h"。在处理该文件时,同样会发生这种情况,直到#include "prokostat.h"指示编译器再次处理该文件为止(请注意,在此之前,除了figura.h的内容外,没有处理任何实际代码) 。在处理(再次)该文件时,它将再次首先处理include防护,发现已经定义了__PROKOSTAT_H__,因此通过在最后对应的#ifndef之前不处理文件的内容来尊重#endif 。然后,编译器将继续处理文件okrag.g(请记住:它仍然没有看到prokostat.h的任何一行实际代码!),并遇到了使用operator>CProkostat朋友定义。但是到目前为止,它没有看到CProkrostat的定义,因此它抱怨未定义的标识符。

现在该如何解决?好吧,最简单的修复方法只是注意到prokostat.h实际上没有引用okostat.h中的任何内容,因此您可以从其中删除#include "okostat.h"。这将打破循环依赖关系,从而解决紧迫的问题。

但是,由于两个原因,它还不是完美的解决方法:首先,如果您需要在COkrak中引用prokostat.h怎么办?其次,每当procostat.h更改时,您都需要重新编译每个文件,包括okrak.h,即使该文件不使用okrak.h中的任何内容。

因此,正确的解决方法不仅是从#include "okrak.h"中删除​​prokostat.h,而且还从#include "prokostat.h"中删除​​okrak.h,而是在该文件的开头(即,在其任何文件之前)添加CProkostat的前向声明。定义)。该前向声明如下所示:

class CProkostat;


这使编译器知道存在该名称的类而无需告知任何详细信息(称为不完整类型)。您不需要那些细节来声明好友函数(但是您需要使用它们来定义好友函数,因此在相应的实现文件中,您必须#include "prokostat.h")。

附带说明一下,您的比较运算符应通过const引用获取对象,以避免不必要的复制。

10-04 17:51