【问题标题】:Using compare operator with two different classes objects将比较运算符与两个不同的类对象一起使用
【发布时间】:2012-04-01 16:38:32
【问题描述】:

我对操作员有疑问。一般来说,我知道使用运算符的基础知识。但是当我想比较两个对象时,我的问题就开始了。我有 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&gt;(COkrag o1, CProstokat o2);

上面写着:Error 1 error C2061: syntax error : identifier 'CProstokat'

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

谁能告诉我怎么了?

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

bool operator&gt;(CProstokat &amp; p2);

但是编译器说

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

现在它可以在没有它的情况下工作。这是我得到的。

#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

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

【问题讨论】:

  • Google 关键字词组是“forward declaration”。
  • 此外,通常的约定是使用英文标识符,而不是您的母语中的标识符。同样,类名开头的“C”大部分时间都很烦人,并且不会使您的代码变得清晰(每个IDE都可以告诉您Circle是类还是其他任何东西,不需要“CCircle”-哪个使其更难阅读)。
  • 这是我的家庭作业,老师需要这种类型的 CClass 声明。但是感谢您的建议,我将在我的私人项目中使用您推荐的符号样式。

标签: c++ class operator-keyword


【解决方案1】:

您在包含中存在循环依赖。您在 okrag.h 中包含 prostokat.h,反之亦然。这样,其中一个包含将不起作用(由于ifndef,您将获得空文件)。

为了解决这个问题,在 okrag.h 的开头添加 CProstokat 类的前向声明:

class CProstokat;

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

【讨论】:

  • 他还需要使用 const refs 作为比较运算符的参数,否则前向声明将不起作用。
  • 另外,您可以对代码进行更大的更改(但这似乎是正确的方法)并在 CFigura 之间实现比较运算符,这将适用于 COkrag 和 CProstokat。
  • 是的,这将是一个很好的解决方案,但我需要比较仅在儿童课程中可用的功能。我会先尝试测试您的建议,然后再次上诉
  • 然后在子类中实现虚拟方法,这些虚拟方法将提供值以在基类中进行比较。
【解决方案2】:

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

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

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

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

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

class CProkostat;

这让编译器知道存在该名称的类,而无需提供任何详细信息(称为不完整类型)。你不需要这些细节来声明友元函数(但是你确实需要它们来定义友元函数,所以在相应的实现文件中你必须#include "prokostat.h")。

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

【讨论】:

  • 非常感谢您的回答。这对我来说是非常有用的建议。我学到了新东西。感谢您的时间。我要回去工作了,我会发布我的效果。
猜你喜欢
  • 2012-11-03
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多