Próbuję zrozumieć spójność błędu, który jest wyrzucany w tym programie:wskaźnik do członka zamieszanie
#include <iostream>
class A{
public:
void test();
int x = 10;
};
void A::test(){
std::cout << x << std::endl; //(1)
std::cout << A::x << std::endl; //(2)
int* p = &x;
//int* q = &A::x; //error: cannot convert 'int A::*' to 'int*' in initialization| //(3)
}
int main(){
const int A::* a = &A::x; //(4)
A b;
b.test();
}
Wyjście jest 10 10
. Napisałem 4 punkty programu, ale (3) to mój największy problem:
- jest pobierany normalnie z poziomu funkcji członka.
x
obiektu jest pobierany za pomocą operatora zakres i lwartością do obiektux
zwrotu.- Po otrzymaniu
A::x
zwrócono wartość lw (2), dlaczego zatem&A::x
nie zwróciint*
, ale zamiast tego zwróciint A::*
? Operator zakresu ma pierwszeństwo przed operatorem&
, więc powinien zostać uruchomiony jako pierwszy, zwracając wartość l, przed podaniem adresu. to znaczy powinienem być taki sam jak&(A::x)
? (Dodawanie nawiasów faktycznie działa po drodze). - Oczywiście nieco inaczej, operator zasięgu odnosi się do członka klasy, ale bez obiektu, do którego się odnosi.
Więc dlaczego dokładnie nie A::x
nie zwróci adres obiektu x
lecz zwraca adres elementu, pomijając pierwszeństwo ::
przed &
?
Myślę, że gdyby działało inaczej, doprowadziłoby to do większej dezorientacji. Ta sama sekwencja identyfikatorów i operatorów, odwołująca się do dokładnie tych samych typów i członków, co oznacza dwie różne rzeczy w zależności od zakresu: brzmi dla mnie jak kłopot. –
@ Johno zdecydowanie. Oryginalnie napisałem "dziwactwo", ale w rzeczywistości jest to bardzo rozsądny wybór, chociaż może wydawać się dziwne na początku. – Quentin