使用compare运算符和两个不同的类对象

时间:2012-04-01 16:38:33

标签: c++ class operator-keyword

我遇到运营商问题。通常我都知道使用运算符的基础知识。但是当我想要比较两个对象时,我的问题开始了。我有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

我希望我理解你的建议。感谢大家花时间回答。

2 个答案:

答案 0 :(得分:1)

您在包含中具有循环依赖关系。你在okrag.h中包含了prostokat.h,反之亦然。这样,其中一个包含将无效(由于ifndef,您将获得空文件。)

要解决此问题,请在okrag.h的开头添加CProstokat类的前向声明:

class CProstokat;

此外,更改运算符的签名以通过const引用获取参数,而不是通过值获取它们。这将改善绩效并促进使用前瞻性声明。

答案 1 :(得分:0)

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

假设某些代码文件包含procostat.h。现在处理procostat.h时,预处理器将首先处理包含保护,定义__PROKOSTAT_H__(侧节点:包含双下划线的所有标识符都保留用于实现;不要将它们用于您自己的代码),然后包括figura.h,然后查找并处理#include "okrag.h"。在处理该文件时,同样会发生,直到#include "prokostat.h",它指示编译器再次 处理该文件(请注意,除此之外,没有任何实际代码,除了内容figura.h已被处理)。在处理(再次)该文件时,它将再次首先处理包含保护,发现__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")。< / p>

作为旁注,您的比较运算符应该通过const引用来获取对象,以避免不必要的复制。