C ++: Warum die Elementfunktion Vorrang vor der globalen Funktion hat

7

Warum hat die Member-Funktion foo im nächsten Programm Vorrang vor dem globalen foo, obwohl die globale foo dem Typ entspricht?

%Vor%     
user890739 16.09.2014, 07:09
quelle

6 Antworten

7

Überlegen Sie sich, was passieren würde, wenn eine globale Funktion, die in Ihrer Codebasis irgendwo deklariert ist (möglicherweise mehrere #include -Absätze entfernt), eine class obj -Memberfunktion, die direkt in der Klasse deklariert ist sich selbst ...

Es würde bedeuten, dass Sie, wenn Sie auf Nummer sicher gehen wollen, jeden einzelnen Aufruf einer Mitgliedfunktion vollständig qualifizieren müssen ...

%Vor%

... anstatt den weniger wahrscheinlichen Fall zu qualifizieren, in dem tatsächlich auf die globale Funktion Bezug genommen wird.

%Vor%

Dies wird als "Konzept der geringsten Überraschung" bezeichnet.

    
DevSolar 16.09.2014, 07:38
quelle
9

Da die Memberfunktion namens foo im Klassenbereich gefunden werden kann und Namenssuche beendet wird, wird die globale Version foo nicht für Überladung berücksichtigt Auflösung , auch wenn die globale Version hier besser geeignet ist. Es ist eine Art Name, der sich versteckt .

Wenn Sie die globale Version aufrufen möchten, können Sie sie explizit mit ::foo(6.4); aufrufen.

Und hier ist ein Workaround, um die globale Funktion in Überladungsauflösung zu bringen.

Referenz für Suche nach nicht qualifizierten Namen

    
songyuanyao 16.09.2014 07:18
quelle
3

Einer der Grundsätze des Methodenüberladens ist, dass das Spezifische das Allgemeine übertrumpfen sollte. In Ihrem Beispiel ist die Elementmethode immer spezifischer als eine globale Methode.

    
llogiq 16.09.2014 07:15
quelle
3

Im Allgemeinen, wenn Bereiche verschachtelt sind, verbirgt jeder im inneren Bereich deklarierte Name alle Objekte mit demselben Namen in einem äußeren Bereich, wenn dieser Name im inneren Bereich verwendet wird. In diesem Fall werden die in der Klasse deklarierten Namen bei der Verwendung im Klassenbereich die im umschließenden Namespace deklarierten Namen ausblenden.

Der äußere Name ist immer noch verfügbar, wenn Sie ihn qualifizieren; In diesem Fall ist es im globalen Namespace als ::foo verfügbar.

    
Mike Seymour 16.09.2014 07:16
quelle
1

Sie können sich eine zunehmende "Spezialisierung" vorstellen, wenn Sie vom globalen Namespace durch verschachtelte Namespaces um Ihre Klasse, verschachtelte Klassen usw. zu den beteiligten Member-Funktionen wechseln. Wenn Sie in diesem inneren Kontext "foo" sagen, kann erwartet werden, dass eine "spezialisierte" foo für den Aufrufer relevanter ist. Wenn der globale Präfix verwendet wurde, konnte jemand, der Symbole zu einem weniger "spezialisierten" Bereich hinzufügt, eine Klasse aufteilen, die ein gleichnamiges Symbol definiert, wodurch viele der Vorteile von Namespaces und ID-Scoping rückgängig gemacht werden. Die Grundidee ist, dass Ihre Klasse viel Freiheit hat, aussagekräftige, aber prägnante Bezeichner zu verwenden - die möglicherweise von anderem Code in Ihrer Anwendung verwendet werden -, aber nur, wenn eine Bedeutung für diesen Bezeichner nicht im lokalsten Bereich verfügbar ist es fängt an, weiter und weiter weg zu schauen.

    
Tony Delroy 16.09.2014 07:18
quelle
1

In Bezug auf die Priorität der Bereichsauflösung (Standard), wenn derselbe Name eines Bezeichners verwendet wird, lokaler Bereich, Mitglied der Klasse (Klassenbereich), globaler Bereich

    
Dr. Debasish Jana 16.09.2014 07:41
quelle

Tags und Links