2011-08-31 8 views
5

w „C++ język programowania”, na stronie 265, autor czyni następujące oświadczenie:Pytanie o predefiniowane znaczeń dla operatorów

powodu historycznego wypadku, operatorzy = (przelew), & (Address z) oraz (sekwencjonowanie; §6.2.2) mają predefiniowane znaczenia, gdy są stosowane do obiektów klasy. Te predefiniowane znaczeń może być niedostępne dla zwykłych użytkowników, czyniąc je private:

Następnie Poniższy przykład podano:

class X { 
private: 
void operator=(const X&); 
void operator&(); 
void operator,(const X&); 
// ... 
}; 

void f(X a, X b) 
{ 
    a = b; // error: operator= private 
    &a;  // error: operator& private 
    a,b; // error: operator, private 
} 

nie mogę zupełnie zrozumieć, co te „błąd” komentarze odnoszą do? Czy to oznacza, że ​​nie powinienem zdefiniować funkcji takiej jak f, czy też wszystkie operatory =, & i , powinny być używane zgodnie z domyślnym sposobem i czy nie jest konieczne ich ponowne zdefiniowanie?

Odpowiedz

8

Ten przykład pokazuje sposób, aby uniemożliwić sobie lub innym twórcom kodu korzystanie z operatorów, z których można korzystać bez zdefiniowania ich w klasie, ponieważ są one generowane automatycznie (i mają domyślne znaczenie dla operacji, które przedstawiać).

Autor przykład oznaczało, że jeśli spróbujesz przypisać do ab (w linii a = b) spowoduje to błąd, ponieważ operator przypisania jest prywatny w definicji klasy.

Podobny błąd występuje w przypadku adresu w drugim wierszu, a przecinek w trzecim.

Domyślne operatory/konstruktorzy prywatne, jeśli wiesz, że nie powinny być używane (lub nie zostały jeszcze zaimplementowane) są dobre, ponieważ można przypadkowo użyć bardzo częstego operatora, takiego jak przypisanie lub konstruktor kopii, będąc nieświadomi, że domyślne zachowanie jest w konflikcie z cyklem życia klasy. Jeśli taki operator lub konstruktor zostanie uczyniony prywatnym na samym początku projektowania klasy, kompilator wygeneruje błąd podczas kompilacji zamiast wykonywania potencjalnie niebezpiecznej operacji bez powiadomienia, jeśli programista przypadkowo użyje tej metody.

Domyślny operator przypisania i wskaźnik elementu: skopiuje wskaźnik, podczas gdy obiekt może być właścicielem danych. Następnie, gdy ktoś przydzieli jeden obiekt do drugiego, nie wiedząc, że przypisanie nie zostało zaimplementowane, otrzymasz podwójny błąd wolny. Zamiast tego, jeśli operator jest prywatny, dostaniesz niezły błąd, a kod nawet się nie skompiluje i będziesz wiedział, co się dzieje.

1

Zapewnienie własnej implementacji dowolnego operatora jest zasadniczo takie samo jak implementacja metody klasy. Operatory i metody są takie same pod względem dostępności. To, co robisz, uniemożliwia dostęp do operatorów z kodu dzwoniącego.

Jest to absolutnie to samo, jeśli zdefiniowano prywatną metodę, a następnie próbowano wywołać ją z kodu, który nie należy do klasy. Upublicznij operatorów, a błędy znikną.

1

Zasadniczo uniemożliwia to stworzenie obiektu "X" i używanie operatorów "=", "&" i "," na tej klasie. Ponieważ autor klasy może implementować te obiekty o znaczeniu, które jest zupełnie inne od tego, co może uważać konsument klasy ... więc najlepiej jak najlepiej zapobiegać ich używaniu w przypadku niejasności.

1

Funkcja f jest przykładem użytkownik próbuje użyć operatorów prywatnych. Pokazuje, jaki kod blokujesz, czyniąc je prywatnymi. Komentarz // error oznacza, że ​​program zawierający tę linię nie skompilowałby się z podanej przyczyny.

5

Autor zamierza tutaj podkreślić, że operatory =, & i , są zwykle niejawnie dostępne dla danej klasy.
Więc jeśli nie chcesz, aby twoje obiekty były obsługiwane przez nich, to deklarujesz je jako private, tym samym uniemożliwiając ich użycie.

Ponieważ są one zadeklarowane jako private, nie można uzyskać do nich dostępu poza klasą, a kompilator zgłosi błąd kompilacji. Funkcja jest tego przykładem.

+0

I ta odpowiedź jest jaśniejsza niż najbardziej upvoted jedno: punkt * * predefiniowanych znaczeń jest to, że są one obecne i działa domyślnie * *, i że jedynym sposobem na hamowanie * * że zachowanie w C++ 03 jest przez deklarowanie ich jako "prywatne" (C++ 0x dodaje słowo kluczowe "delete") –

0

Przed omawianiem błędu, kluczem jest zrozumienie, że te operacje będą domyślnie udostępnione dla twojej klasy. To jest esencja porady Scotta Meyersa "Wie, jakie funkcje C++ cicho pisze i dzwoni".

C++ automatycznie zaimplementować operator przypisania dla swojej klasy, ale to nie może być prawidłowo wykonane (na przykład, jeśli twoja klasa zawiera zmienną składową wskaźnika). Przez jednoznaczne zdefiniowanie operatora przypisania, mówisz kompilatorowi, aby używał twojej implementacji, zamiast ją generować. A czyniąc to prywatnym, zasadniczo uniemożliwiasz przypisanie jednej instancji klasy do drugiej. Gdziekolwiek spróbujesz to zrobić w swoim kodzie, kompilator będzie narzekał, co jest dobre, jeśli naprawdę nie chcesz, aby zadanie zostało wykonane.

W funkcja f autora pokazuje, że te wypowiedzi nie będzie kompilować, ponieważ, jak operatorzy są zdefiniowane w klasie. Całkowicie dopuszczalne jest przedefiniowanie operatorów dla twojej klasy, a czasami jest to zdecydowanie wymagane (na przykład, aby zaimplementować głęboką kopię zmiennej wskaźnika wskaźnika w twojej klasie). Celem tego przykładu jest pokazanie, że a) możesz podać własną implementację tych operatorów dla swojej klasy, oraz b) z tego powodu masz kontrolę nad tym, czy operatorzy są obsługiwani i prawidłowo zaimplementowani w klasie.