2012-04-09 10 views
2

Ich teste gerade eine Datei und ich habe eine Situation, wo ich auf einige der geschützten Mitglieder der Klasse von main.cpp zugreifen muss. Ich habe versucht, hinzuzufügen, main() als Freund, arbeitete nicht aus und lernte, dass es nicht funktioniert, so bewegte ich alles in main() zu einem test() und machte die test() als Freund. immer noch zeigt es den Fehler.Muss sich die Friend-Funktion in derselben Datei befinden?

Beispiel würde

//--File.hpp 

namespace Files { 

class File { 
      public: 
       File(long word_):word(word_) {} 
      protected: 
       long word; 
      private: 
       friend int test(); 
}; 
}//ns:Files 


//--List_File.hpp 

namespace Files { 
class List_File :public File { 
     public: 
       List_File() : File(sizeof(int) + sizeof(long)) {} 
     private: 
       friend int test(); 
}; 
}//ns:Files 



//--main.cpp 

    using namespace Files; 

    int test() { 

     File *pd = new List_File(); 
     assert(pd->word == 12); //LINE 34 
     return 0; 
    } 

    int main() { 
     test(); 
     return 0; 
    } 

sein // heißt es Fehler in Zeile 34: Basis :: Wert geschützt. Bitte um Rat.

g++ -O -Wall -Wno-unused -o a.out File.cpp List_File.cpp Data_File.cpp    
    Free_List_File.cpp main.cpp 
    File.hpp: In function ‘int test()’: 
    File.hpp:30:7: error: ‘long int Files::File::word’ is protected 
    main.cpp:34:16: error: within this context 
    make: *** [a.out] Error 1 
+0

für mich der entsandte Code kompiliert fein aktualisiert (unter G ++ 4.2), nachdem ich die abgeleitete Klasse Erklärung geändert (es sollte sagen: „Klasse Derived: public Base“, aber die ": public Base" fehlt) –

+0

yeah yeah öffentliche basis ist da .. ich werde nochmal nachschauen. – howtechstuffworks

+0

@ JeremyFriesner Es ist seltsam, dass das obige Code-Snippet den gleichen Fehler ausgibt, wenn es mit meinem g ++ 4.4.5 kompiliert wird. Hat es etwas mit Namensraum zu tun? Ich meine, vielleicht sollten Sie 'test' im Namespace' Files' implementieren. Kann keine Tonreferenz finden, also nur einen Kommentar. –

Antwort

1

Nein, es ist auf jeden Fall nicht in der gleichen Datei sein, aber es hat offensichtlich zu „wissen“, was die Klasse ist, das heißt: der Header, der die Klassendefinition hat, sollte in der Datei enthalten sein wo die Funktion implementiert ist. Ihr Code sollte in Ordnung sein, wie kommentiert.

nachdem Sie einige Kontext hinzugefügt

Ihre test Funktion ist nicht im Files Namespace. Wenn Sie möchten, dass es sich im globalen Kontext befindet, sollten Sie es als "::test" innerhalb des Namespace behandeln, andernfalls könnte der Compiler die "Files::test" die Friend-Funktion und nicht die "::test" wie in Ihrem Fall erwarten. Ich kann den formellen Standardreferenz nicht finden, aber ich bin ziemlich sicher, dass das der Fall ist. Beachten Sie, dass Sie hier eine Forward-Deklaration durchführen, daher gibt es keinen Standard-Fallback auf die obere Ebene des Bereichs für die Namensauflösung.

+0

Ja, genau das wah ich, dachte ich. Nicht ganz sicher, warum es den Fehler zeigt.Werde bald wieder hier sein, um zu sehen, ob irgendetwas anderes den Zugriff auf – howtechstuffworks

+0

verhindert. @howtechstuffworks wäre nett von dir, den Fehler tatsächlich zu zitieren :-) – littleadv

+0

Wirkt sich Namespace auf irgendetwas aus? Weil ich jedoch auf die öffentlichen Variablen zugreifen konnte. Oder sonst, muss ich den Zugriffsspezifizierer unter dem bestimmten geschützten oder irgendetwas erwähnen? – howtechstuffworks

1

Vielleicht fehlt Ihnen die Vererbung in der abgeleiteten Klasse?

class Derived : public Base { 

Ich habe Ihren Code (mit Vererbung Erklärung enthalten) getestet und es erzeugt keine Fehler

+0

Nein, ich habe diesen Code getippt, da mein Code zu groß ist ...... Aber nicht sicher, warum es hier den Fehler macht ... – howtechstuffworks

-1

Ich würde vermuten, dass Sie eine geschützte Variable außerhalb des Bereichs der Dateien Klassendefinition zuzugreifen versuchen. Ich würde eine Funktion empfehlen, die das Variablenwort zurückgibt, wenn es aufgerufen wird, und das verwenden, anstatt zu versuchen, auf eine geschützte Variable außerhalb einer Klassendefinition zuzugreifen. Ich könnte mich irren, weil ich nicht wirklich sicher bin, was der Umfang einer geschützten Variablen ist (ob sie nur auf Klassendeklarationen beschränkt ist oder ob auf sie außerhalb der Klassendefinition zugegriffen werden kann), aber ich bin mir ziemlich sicher, weil geschützte Variablen sind wie private Variablen. Sie sind nur innerhalb des Klassenbereichs zugänglich. Korrigiere mich, wenn ich falsch liege.

EDIT: Oh, es tut mir leid, ich wusste nicht, was Sie getan haben. littleadv hat Recht, Ihre Funktionsdeklaration befindet sich nicht im Datei-Namespace.

+1

Yeah Du hast Recht, geschützte und private Variablen sind nur innerhalb der Klasse zugänglich, aber was ist der Punkt der Freundin dann funktionieren. Ich benutze es immer noch ich bekomme einen Fehler. Lass mich sehen. Ich habe genau das getan, was du gesagt hast, aber ich werde das gleiche Szenario noch einmal versuchen und debuggen, sobald ich diese Aufgabe beende, werde ich euch updaten – howtechstuffworks

0

littedev ist richtig !! den Code nach den Kommentaren von littedev ..

//--File.hpp 
namespace Files { 
    class File { 
     public: 
      File(long word_):word(word_) {} 
     protected: 
      long word; 
     private: 
      friend int test(); 
    }; 
}//ns:Files  

//--List_File.hpp 

namespace Files { 
    class List_File :public File { 
     public: 
      List_File() : File(sizeof(int) + sizeof(long)) {}   \ 
     private: 
      friend int test(); 
    };  
}//ns:Files  

//--main.cpp  

namespace Files{  
    int test() {   
     File *pd = new List_File(); 
     assert(pd->word == 12); //LINE 34 
     return 0; 
    } 

    int main() { 
     Files::test(); 
     return 0; 
    } 
}