Greifen Sie auf die in der Klasse definierte Freundesfunktion zu

Lesezeit: 3 Minuten

Es gibt einen solchen Code:

#include <iostream>

class A{

public:
    friend void fun(A a){std::cout << "Im here" << std::endl;}
    friend void fun2(){ std::cout << "Im here2" << std::endl; }
    friend void fun3();
};

void fun3(){
    std::cout << "Im here3" << std::endl;
}

int main() 
{  
    fun(A()); // works ok
    //fun2(); error: 'fun2' was not declared in this scope
    //A::fun2(); error: 'fun2' is not a member of 'A'
    fun3(); // works ok
} 

Wie greife ich auf die Funktion fun2() zu?

  • +1: Gut formulierte Frage.

    – Leichtigkeitsrennen im Orbit

    16. Oktober 2011 um 17:26 Uhr

  • Wir sehen diese Art von Code im intelligenten Zeiger von boost: intrusive_ptr, was mich zunächst verwirrte, was das sein sollte. Für mich macht es keinen Sinn, es so zu definieren, sondern irgendwo im Bereich einen Freund zu definieren und einen Prototyp in der Klassenbereichsdeklaration als Freund zu markieren, was besser lesbar ist!

    – Gabriel

    14. Juni 2014 um 14:59 Uhr

class A{

public:
    friend void fun(A a){std::cout << "Im here" << std::endl;}
    friend void fun2(){ std::cout << "Im here2" << std::endl; }
    friend void fun3();
};

Obwohl Ihre Definition von fun2 tut Definieren Sie eine “globale” Funktion anstelle eines Members und machen Sie sie zu einer friend von A Gleichzeitig fehlt Ihnen immer noch eine Deklaration derselben Funktion im globalen Geltungsbereich selbst.

Das bedeutet, dass kein Code in diesem Bereich eine Ahnung davon hat fun2 existiert.

Das gleiche Problem tritt z funaußer dass die argumentabhängige Suche die Funktion übernehmen und finden kann, da ein Argument vom Typ vorhanden ist A.

Ich empfehle stattdessen, Ihre Funktionen auf die übliche Weise zu definieren:

class A {
   friend void fun(A a);
   friend void fun2();
   friend void fun3();
};

void fun(A a) { std::cout << "I'm here"  << std::endl; }
void fun2()   { std::cout << "I'm here2" << std::endl; }
void fun3();

Beachten Sie das jetzt alles funktioniert (außer fun3 weil ich es nie definiert habe).

Greifen Sie auf die in der Klasse definierte Freundesfunktion zu
CB Bailey

Der Grund, warum Sie anrufen können fun ist das die Friend-Deklaration innerhalb der Klasse A macht es nur über argumentabhängige Suche sichtbar. Andernfalls machen Friend-Deklarationen die Funktionen, die sie deklarieren, nicht automatisch außerhalb des Klassenbereichs sichtbar, in dem sie erscheinen.

Sie müssen eine Deklaration im Namespace-Bereich oder innerhalb hinzufügen main zu machen fun2 sichtbar darin main.

Z.B

void fun2();

fun3 ist innen sichtbar main weil ihre Definition (außerhalb der Klasse) auch eine Deklaration ist, die sie sichtbar macht main.

ISO/IEC 14882:2011 7.3.1.2:

Der Name des Freundes wird nicht durch unqualifiziertes Nachschlagen (3.4.1) oder durch qualifiziertes Nachschlagen (3.4.3) gefunden, bis eine übereinstimmende Deklaration in diesem Namensraumbereich bereitgestellt wird (entweder vor oder nach der Klassendefinition, die Freundschaft gewährt).

3.4.2 (Argumentabhängige Namenssuche) / 4:

Alle Friend-Funktionen im Namensraumbereich oder Friend-Funktionsvorlagen, die in zugeordneten Klassen deklariert sind, sind in ihren jeweiligen Namensräumen sichtbar, selbst wenn sie während einer gewöhnlichen Suche (11.3) nicht sichtbar sind.

  • Das Platzieren der Deklaration im globalen Namensraum löst das Problem, aber das Platzieren in der Hauptfunktion erzeugt einen Linker-Fehler. Danke.

    – scdmb

    16. Oktober 2011 um 17:18 Uhr


  • @scdmb: Ich bin überrascht über den Linker-Fehler, er sollte gültig sein.

    – CB Bailey

    16. Oktober 2011 um 17:21 Uhr

  • Nein, Platzierung der Definitionserklärung in main verursacht a Compiler Error. Was Charles vorgeschlagen hat, ist richtig. Und das nächste Mal stellen Sie bitte jedes Mal einen Testfall bereit, wenn Sie mit einem solchen Fehlerbericht zurückkommen. In Ihrem C++-Buch finden Sie den Unterschied zwischen einer Deklaration und einer Definition.

    – Leichtigkeitsrennen im Orbit

    16. Oktober 2011 um 17:21 Uhr


  • @TomalakGeret’kal: Ich bekomme auch den Linker-Fehler, kannst du mir helfen, wo ich es falsch verstanden habe?

    – CB Bailey

    16. Oktober 2011 um 17:24 Uhr

  • @Charles: codepad.org Mal sehen! Hat meine Arbeitspaste Ihren Vorschlag zur Abgabe der Erklärung nicht genau wiedergegeben? main?

    – Leichtigkeitsrennen im Orbit

    16. Oktober 2011 um 17:25 Uhr


915780cookie-checkGreifen Sie auf die in der Klasse definierte Freundesfunktion zu

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy