【问题标题】:Does the friend function have to be in the same file?朋友功能是否必须在同一个文件中?
【发布时间】:2012-04-21 12:04:11
【问题描述】:

我实际上是在测试一个文件,我有一种情况,我需要从 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

【问题讨论】:

  • 在我修改了派生类声明之后,发布的代码对我来说编译得很好(在 G++ 4.2 下)(它应该说“类派生:公共基础”,但“:公共基础”不见了)
  • 是的,公共基地在那里..我会再检查一次。
  • @JeremyFriesner 奇怪的是,上面的代码 sn-p 在使用我的 g++ 4.4.5 编译时会出现同样的错误。它与命名空间有关吗?我的意思是也许你应该在命名空间Files 中实现test。找不到可靠的参考,所以只是评论。

标签: c++ inheritance friend protected access-specifier


【解决方案1】:

不,它绝对不必在同一个文件中,但它显然必须“知道”类是什么,即:具有类定义的头文件应该包含在函数所在的文件中实施的。正如评论的那样,您的代码应该没问题。

添加一些上下文后

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

【讨论】:

  • 是的,我就是这么想的。不太确定,为什么它显示错误。很快就会回到这里,看看是否有其他东西阻止访问
  • @howtechstuffworks 很高兴你能实际引用错误:-)
  • 命名空间会影响什么吗?因为,我可以访问公共变量。或者,我是否需要在特定的受保护或任何内容下提及访问说明符?
  • @howtechstuffworks 绝对有效。您为什么不在一小段代码中重现您的问题,然后按原样发布,以便我们可以看到问题?您发布的代码很好,您显然还有其他东西(顺便说一句:我假设 main.cpp 包含 Derived.hpp,而 Derived.hpp 包含 Base.hpp,但如果不是这样,您会遇到其他问题)。
【解决方案2】:

也许您在 Derived 类中缺少继承声明?

 class Derived : public Base {

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

【讨论】:

  • 不,我手动输入了这段代码,因为我的代码太大了......但不知道为什么它会在这里出错......
【解决方案3】:

我猜你正在尝试访问 Files 类定义范围之外的受保护变量。我会推荐一个函数,它在被调用时返回变量 word 并使用它而不是尝试访问类定义之外的受保护变量。我可能是错的,因为我不确定受保护变量的范围是什么(它是否仅限于类声明或是否可以在类定义之外访问),但我很确定我是对的,因为受保护的变量就像私有变量。它们只能在类范围内访问。如果我错了,请纠正我。

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

【讨论】:

  • 是的,你是对的,受保护的和私有的变量只能在类内部访问,但是朋友函数的意义何在。我正在使用它仍然出现错误。让我看看。我完全按照你说的做了,但是会再次尝试相同的场景并调试,一旦我完成了这个任务,会更新你们
【解决方案4】:

littedev 是对的! 根据littedev的cmets更新了代码..

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

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 2020-06-04
    • 2017-11-28
    • 2015-09-29
    • 1970-01-01
    • 2015-11-24
    • 2011-04-17
    • 1970-01-01
    相关资源
    最近更新 更多