2

I am actually testing a file and I have a situation, where I need to access some of the protected members of the class from main.cpp. I tried to add, main() as friend, didn't work out and learned that it wont work, so I moved everything in the main() to a test () and made the test() as friend. still it shows the error.

Example would be

 //--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;
  }

//it says error on Line 34: Base::value is protected. Please advice.

    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
howtechstuffworks
  • 1,824
  • 4
  • 29
  • 46
  • The posted code compiled fine for me (under G++ 4.2), after I modified the Derived class declaration (it should say "class Derived : public Base", but the ": public Base" is missing) – Jeremy Friesner Apr 09 '12 at 00:39
  • yeah yeah public base is there.. I will check again. – howtechstuffworks Apr 09 '12 at 00:43
  • @JeremyFriesner It is strange the above code snippet issues the same error when compiled with my g++ 4.4.5. Is it something related to namespace? I mean maybe you should implement `test` in namespace `Files`. Can't find a sound reference, so just a comment. – Summer_More_More_Tea Apr 09 '12 at 02:31

4 Answers4

2

No, it definitely doesn't have to be in the same file, but it obviously has to "know" what the class is, i.e.: the header that has the class definition should be included in the file where the function is implemented. Your code should be fine, as commented.

after you added some context

Your test function is not in the Files namespace. If you want it to be in the global context, you should treat it as "::test" within the namespace, otherwise the compiler might expect the "Files::test" to be the friend function, and not the "::test" as in your case. Can't find the formal standard reference, but I'm pretty sure that's the case. Note that you're performing a forward declaration here, so there's no default fall-back to the upper level of scope for name resolution.

littleadv
  • 20,100
  • 2
  • 36
  • 50
  • Yeah, exactly thats waht I thought. Not quite sure, why its showing the error. Will get back here soon, to see if anything else is preventing from accessing – howtechstuffworks Apr 09 '12 at 00:47
  • @howtechstuffworks would be nice of you to actually quote the error:-) – littleadv Apr 09 '12 at 00:49
  • Will namespace affect anything? Because, I could access the public variables though. Or else, Do I need to mention the access specifier under the particular protected or anything? – howtechstuffworks Apr 09 '12 at 00:50
  • @howtechstuffworks definitely. Why don't you reproduce your problem in a small piece of code, and then post it as is so that we could see the problem? the code you posted is fine, you obviously have something else (BTW: I'm assuming main.cpp includes Derived.hpp, and Derived.hpp includes Base.hpp, but you would have other problems if it wasn't so). – littleadv Apr 09 '12 at 00:52
1

Maybe you missing inheritance declaration in Derived class?

 class Derived : public Base {

I've tested your code (with inheritance declaration included) and it produced no error

Thanh Nguyen
  • 161
  • 1
  • 10
0

littedev is right!! Updated the code according to the comments by 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;
    } 
}
andrewsi
  • 10,807
  • 132
  • 35
  • 51
-1

I would guess that you are trying to access a protected variable outside of the scope of the Files class definition. I would recommend a function that returns the variable word when it is called and use that instead of trying to access a protected variable outside of a class definition. I could be wrong in that I am not really sure what is the scope of a protected variable (whether it is limited only to class declarations or whether it can be accessed outside of the class definition) but I am pretty sure that I am right because protected variables are like private variables. They are only accessible within the class scope. Correct me if I am wrong.

EDIT: Oh I am sorry I didn't realize what you were doing. littleadv is right, your function declaration isn't within the files namespace.

Jason Zhu
  • 2,194
  • 3
  • 23
  • 27
  • 1
    Yeah You are right, protected and private variables are accessible only inside class, but whats the point of friend function then. I am using it still I am getting an error. Let me see. I did exactly what you said, but will try the same scenario again and debug, once I finish this assignment, will update u guys – howtechstuffworks Apr 09 '12 at 02:26