C++ friend函数必须在同一个文件中吗?

C++ friend函数必须在同一个文件中吗?,c++,inheritance,friend,protected,access-specifier,C++,Inheritance,Friend,Protected,Access Specifier,实际上我正在测试一个文件,我遇到了一种情况,我需要从main.cpp访问类的一些受保护成员。我试图添加,main()作为朋友,但没有成功,并且知道它不会成功,所以我将main()中的所有内容都移动到test()中,并将test()作为朋友。但它仍然显示了错误 例如 //--File.hpp namespace Files { class File { public: File(long word_):word(word_) {}

实际上我正在测试一个文件,我遇到了一种情况,我需要从main.cpp访问类的一些受保护成员。我试图添加,
main()
作为朋友,但没有成功,并且知道它不会成功,所以我将
main()
中的所有内容都移动到
test()
中,并将
test()
作为朋友。但它仍然显示了错误

例如

 //--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;
  }
//它说第34行的错误:Base::value受到保护。请给我一些建议

    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

不,它肯定不必在同一个文件中,但它显然必须“知道”类是什么,即:具有类定义的头应该包含在实现函数的文件中。正如所评论的,您的代码应该很好

在添加一些上下文后


您的
测试
函数不在
文件
命名空间中。如果希望它位于全局上下文中,则应将其视为命名空间中的“
::test
”,否则编译器可能会认为“
文件::test
”是友元函数,而不是像您的情况那样的“
::test
”。找不到正式的标准参考,但我很确定是这样的。请注意,您在这里执行的是一个正向声明,因此在名称解析中没有默认的回退到作用域的上层。

可能您在派生类中缺少继承声明

 class Derived : public Base {

我已经测试了您的代码(包括继承声明),它没有产生任何错误

我猜您正在尝试访问文件类定义范围之外的受保护变量。我建议使用一个函数,在调用时返回变量字,并使用它,而不是试图访问类定义之外的受保护变量。我可能是错的,因为我不确定受保护变量的作用域是什么(它是否仅限于类声明或是否可以在类定义之外访问),但我非常确定我是对的,因为受保护变量类似于私有变量。它们只能在类范围内访问。如果我错了,请纠正我

编辑:哦,对不起,我没有意识到你在做什么。LittledV是对的,您的函数声明不在文件命名空间内

利特德夫是对的!! 根据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;
    } 
}

在我修改了派生类声明(应该是“class-Derived:public-Base”,但是“:public-Base”丢失)之后,发布的代码对我来说编译得很好(在G++4.2下)。。我会再次检查。@JeremyFriesner奇怪的是,上面的代码片段在使用我的g++4.4.5编译时会出现同样的错误。它与名称空间有关吗?我的意思是,也许您应该在命名空间
文件
中实现
test
。找不到可靠的参考资料,所以只是一个评论。是的,我就是这么想的。不太清楚,为什么会显示错误。我很快就会回来,看看有没有其他事情阻止我accessing@howtechstuffworks请您实际引用错误:-)名称空间会影响任何事情吗?因为,我可以访问公共变量。或者,我需要提及特定受保护项下的访问说明符吗?howtechstuff肯定有效。为什么不在一小段代码中重现您的问题,然后按原样发布,以便我们可以看到问题?你发布的代码很好,你显然还有其他东西(顺便说一句:我假设main.cpp包括Derived.hpp,Derived.hpp包括Base.hpp,但如果不是这样,你会有其他问题)。不,我手工输入了这段代码,因为我的代码太大了。。。。。。但不确定为什么会出现错误……是的,你是对的,受保护和私有变量只能在类内访问,但是friend函数的意义何在。我正在使用它,但我仍然得到一个错误。我想一下。我完全按照你说的做了,但是我会再次尝试相同的场景,并且调试,一旦我完成了这个任务,我会更新你们