我遇到运营商问题。通常我都知道使用运算符的基础知识。但是当我想要比较两个对象时,我的问题开始了。我有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
我希望我理解你的建议。感谢大家花时间回答。
答案 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引用来获取对象,以避免不必要的复制。