tworzenie implicit obiektu klasy

tworzenie implicit obiektu klasy
FV
  • Rejestracja:około 6 lat
  • Ostatnio:3 miesiące
  • Postów:96
0

Hej

Dla tego przypadku:

Kopiuj
#include <stdio.h>
#include <iostream>

class A {
  public:
     A(int x):y(x) 
     { 
         std::cout << y << std::endl;
     }
     
     bool operator==(const A& a)
     {
         return a.y == this->y;
     }
     
     bool operator>=(const A& a)
     {
         return this->y >= a.y;
     }
     
     int y;
};

int main()
{
    A(6) == A(6) >= A(5); //najpierw operacja >= bo ma wiekszy priorytet niz ==

    return 0;
}

output programu to 5,6,1,6
czyli niejawnie sie kontruktor stworzyl.
A dla tego błąd, trzeba operator porównywania deklarować i to poza klasą (w klasie nie pomaga):

Kopiuj
#include <stdio.h>
#include <iostream>

class A {
  public:
     A(int x):y(x) 
     { 
         std::cout << y << std::endl;
     }
     
     bool operator==(const A& a)
     {
         return a.y == this->y;
     }
     
     bool operator>=(const A& a)
     {
         return this->y >= a.y;
     }
     
     int y;
};

/*bool operator==(bool x, const A& a)
{
    return (int)x == a.y;
}*/  //to musze odkomentowac by nie było błędu main.cpp:40:18: error: no match for ‘operator==’ (operand types are ‘bool’ and ‘A’)

int main()
{
    A(6) >= A(5) == A(6); //nie potrafi wywolac implicit kontruktora tutaj przed porównywaniem

    return 0;
}

Ktoś wie czemu tak jest że w jednym przypadku nie trzeba operatora porównywania a w drugim trzeba?

edytowany 1x, ostatnio: fvg
TomaszLiMoon
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:530
0

Operator == zdefiniowany wewnątrz klasy nie jest symetryczny. Aby zadziałał po lewej stronie zawsze musi być obiekt typu A.

Kopiuj
// Pierwszy przypadek
(1) A(6) == A(6) >= A(5);
(2) A(6) == true ;
(3) A(6) == 1;  // niejawna konwersja do int
(4) A(6).operator==( 1 );  //  próba wywołania, funkcja nie przyjmuje wartości typu int, ale można użyć niejawnej konwersji z int to A. 
(5) A(6).operator==( A(1) ); // ostatecznie

// Drugi przypadek
(1) A(6) >= A(5) == A(6);
(2) true == A(6);  // błąd po lewej stronie typ bool , a po prawej typ obiektu nie może być zamieniony na bool

Dlatego w drugim przypadku wystarczy zamienić

Kopiuj
A(6) >= A(5) == A(6);

na

Kopiuj
A( A(6) >= A(5) ) == A(6);

IMHO bardziej czytelnym rozwiązaniem okazuje się tutaj zdefiniowanie operatora == na zewnątrz klasy.

Osobna kwestią jest poprawność powyższych przykładów od strony formalnej. Jaki jest sens porównania wartości typu bool z obiektem klasy A?

edytowany 6x, ostatnio: TomaszLiMoon
MarekR22
Jaki jest sens dla: A(true)?
06
  • Rejestracja:prawie 20 lat
  • Ostatnio:około rok
  • Postów:2440
0

Jeśli przy porównaniu dwa operandy są różnego typu, następuje próba konwersji prawego operandu na typ lewego. Dlatego pierwszy przykład działa - bool daje się przekonwertować na A. Drugi przykład nie działa, bo A nie da się przekonwertować na bool. Dodaj operator konwersji na bool i zacznie działać.

edytowany 1x, ostatnio: _0x666_
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:minuta
1

Operatorów porównania nie można łączyć w takie ciągi i dlatego masz błąd.
Dlatego ta linijka: A(6) >= A(5) == A(6); jest bezsensu.
Na dodatek, nawet po poprawce, dalej jest bezsensu, bo z wynikiem trzeba coś zrobić.

Efektywnie ta linijka próbuje zrobić coś takiego:

Kopiuj
{
    bool tmp = A(6) >= A(5);
    tmp  == A(6);
}

Radziłbym opanować najpierw podstawy składni C++ zanim się weźmiesz za przeładowywanie operatorów.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22
enedil
Z całym szacunkiem, też to zauważyłem, ale zdaje się że autor jest doskonale świadomy tego faktu (co widać przez to, że przyznał, że wykonuje się niejawnie konstruktor A(bool)).
enedil
Być może taka operacja nic sensownego nie wyraża, ale jak najbardziej jest sens rozważać jej semantykę.
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:minuta
0

Dobra, nie doczytałem opisu problemu.

A cały problem rozchodzi się o to, że bool operator==(const A& b, const A& a) nie jest dokładnie tym samym co: bool A::operator==(const A& a) const.
Dowód: https://www.godbolt.org/z/vmEzGN

Nie chce mi się szukać wyjaśnienia w standardzie.
Generalnie chodzi o to, że operator zdefiniowany jako metoda klasy jest widoczny w zakresie klasy.
Jak pierwszym argumentem jest typ tej klasy, to operator staje się widoczny w wyrażeniu.
Jeśli pierwszym argumentem jest inny typ, to wtedy operator zdefiniowany jako metoda, nie bierze udziału w rozwiązywaniu przeładowywania operatorów, więc nie ma jak dość do domyślnej konwersji.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.