2012-04-01 192 views
0

我對運算符有問題。通常我知道使用操作符的基本知識。但是當我想比較兩個對象時,我的問題就開始了。我有兩個不同的類聲明文件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 

我希望我能正確理解您的建議。感謝大家花時間回答問題。

+3

Google關鍵字短語是「* forward declaration *」。 – 2012-04-01 16:39:40

+0

此外,通用慣例是使用英文標識符,而不是使用您的母語。類似地,類名開頭的「C」大部分時間都令人惱火,並且不會爲您的代碼帶來任何清晰度(每個IDE都可以告訴您「Circle」是類還是其他任何內容,不需要「CCircle」 - 哪個使其更難以閱讀)。 – Griwes 2012-04-01 16:42:56

+0

這是我的作業任務,老師需要這種類型的CClass聲明。但是,謝謝你的建議,我會用你的建議符號風格到我的私人項目。 – 2012-04-01 16:49:27

回答

0

的問題是,頭文件包括彼此。這將導致以下情況:

假設一些代碼文件包括procostat.h。現在處理procostat.h當預處理程序首先會處理包括後衛,定義__PROKOSTAT_H__(側節點:含雙下劃線被保留用於執行所有的標識符;不要使用他們自己的代碼),然後包括figura.h,然後找到並處理#include "okrag.h"。在該文件的處理,同樣會發生,直到#include "prokostat.h",它指示編譯器再次該文件(注意,直到這一點,沒有任何的實際代碼,除了的figura.h內容,已處理)的過程。在處理(再次)該文件時,它將再次首先處理包含防護,發現__PROKOSTAT_H__已被定義,因此由而不是處理文件的內容,直到相應的#endif結束。然後編譯器將繼續處理文件okrag.g(請記住:它仍然沒有看到來自prokostat.h的實際代碼的單行!)並且遇到使用CProkostat的朋友定義operator>。但到目前爲止,它沒有看到的定義CProkrostat,因此它抱怨未定義的標識符。

現在該如何解決?那麼,最簡​​單的修復方法是注意到prokostat.h實際上並沒有引用okostat.h中的任何內容,因此您可以從中刪除#include "okostat.h"。這將打破循環依賴並因此解決眼前的問題。

但是它還不是完美的解決方案,原因有兩個:首先,如果您需要參考 prokostat.h?其次,只要okrak.h發生變化,即使文件不使用okrak.h,也需要重新編譯每個文件,包括procostat.h

因此,正確的解決方法是不僅刪除prokostat.h#include "okrak.h"另外okrak.h刪除#include "prokostat.h",而是在該文件的開頭(即之前的任何其定義的)添加向前聲明CProkostat 。這種前瞻性聲明如下所示:

class CProkostat; 

這讓編譯器知道存在一個類名沒有告訴任何的細節(這就是所謂的不完全類型)。你不需要這些細節來聲明好友功能(不過你需要需要他們來定義好友功能,所以在相應的實現文件中你必須使用#include "prokostat.h")。

作爲一個方面說明,您的比較運算符應該通過const引用來獲取對象,以避免不必要的複製。

+0

非常感謝您的回答。對我來說這是非常有用的建議。我學到了新東西。謝謝你的時間。我要回去工作,我會發布我的效果。 – 2012-04-01 17:20:43

1

你在include中有循環依賴。您可以在okrag.h中包含prostokat.h,反之亦然。這樣,其中一個包含將不起作用(由於ifndef,您將獲得空文件)。

爲了解決這個問題,在okrag.h的開頭添加類CProstokat的向前聲明:

class CProstokat; 

而且,你的運營商的變化特徵由常數引用而不是按值讓他們得到論證。這既能提高性能,又能促進使用前向聲明。

+2

他還需要使用const refs作爲比較運算符的參數,否則前向聲明將不起作用。 – 2012-04-01 16:45:31

+0

或者,您可以在代碼中做出更大的更改(但這似乎是正確的方式)並在CFigura之間實現比較運算符,該運算符可用於COkrag和CProstokat。 – stanwise 2012-04-01 16:45:51

+0

是的,這將是一個很好的解決方案,但我需要比較僅在兒童課程中可用的功能。我會嘗試第一次測試你的建議,然後我再次上訴 – 2012-04-01 16:54:58