Использование оператора сравнения с двумя объектами разных классов - PullRequest
0 голосов
/ 01 апреля 2012

У меня проблема с операторами. Вообще я знаю основы использования операторов. Но моя проблема начинается, когда я хочу сравнить два объекта. У меня есть 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, но заголовочный файл с объявлением этого класса был включен.

Может кто-нибудь сказать мне, что не так?

EDIT: Я исправил свой код, и вот что я получаю. Я не знаю, почему я не мог добавить 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 ]

1 голос
/ 01 апреля 2012

У вас есть круговая зависимость во включениях. Вы включаете prostokat.h в okrag.h и наоборот. Таким образом, одно из включений не будет работать (вы получите пустой файл из-за ifndef).

Для решения этой проблемы добавьте предварительную декларацию класса CProstokat в начале okrag.h:

class CProstokat;

Кроме того, измените сигнатуры ваших операторов, чтобы получать аргументы по константным ссылкам, а не по значениям. Это улучшит производительность и облегчит использование предварительного объявления.

0 голосов
/ 01 апреля 2012

Проблема в том, что заголовочные файлы включают друг друга .Это приведет к следующему сценарию:

Предположим, что некоторые файлы кода включают 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;

Это позволяет компилятору знать, что класс с таким именем существует, не сообщая ни одной детали (он называется неполным типом).Вам не нужны эти детали для объявления функции-друга (однако вам do они нужны для определения функции-друга, поэтому в соответствующем файле реализации вам нужно будет #include "prokostat.h").

В качестве примечания, ваши операторы сравнения должны брать объекты по константной ссылке, чтобы избежать ненужного копирования.

...