我对接线员有疑问。通常,我知道使用运算符的基础知识。但是,当我想比较两个对象时,我的问题就开始了。我有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引用获取对象,以避免不必要的复制。