【问题标题】:How to use friend function when the class is written inside the namespace当类写在命名空间内时如何使用友元函数
【发布时间】:2012-02-04 15:21:31
【问题描述】:

我在命名空间内创建了一个类,现在当我必须使用或调用命名空间时出现问题,编译器错误的可能原因是什么?

namespace name1    
{   
        class show   
    {   
        int a,b;   
        void accept_data(void);   
        void display_data(void);   
        friend void use_class(void);  
    };  
}

编译器错误 -

test1.cpp:在函数“void use_class()”中:
test1.cpp:17:6: 错误:‘void name1::show::accept_data()’是私有的
test1.cpp:31:16: 错误:在此上下文中
test1.cpp:24:6: 错误:‘void name1::show::display_data()’是私有的
test1.cpp:32:17: 错误:在这个上下文中

【问题讨论】:

  • use_class 声明在哪里?
  • 在命名空间外声明
  • 你需要告诉我们编译器错误是什么
  • 如果我删除命名空间,那么同样的程序运行起来非常容易

标签: c++ namespaces friend-function


【解决方案1】:

当您使用非限定标识符(如use_class)声明友元函数时,该声明始终命名该声明所在类的最近封闭命名空间的成员。函数的先前声明不必是可见的。这意味着您的声明将函数 void ::name1::use_class() 声明为类 ::name1::show 的朋友。

如果你想从不同的命名空间声明一个朋友,你必须使用一个合格的 id。

例如

friend void ::use_class();

请注意,与不合格的情况不同,之前声明的函数必须是可见的。例如

void use_class();
namespace name1 {
    class show {
    //...
    friend void ::use_class();
    //...
    };
}

【讨论】:

    【解决方案2】:

    你可以有这个:

    namespace name1    
    {   
            class show   
        {   
            int a,b;   
            void accept_data(void);   
            void display_data(void);   
            friend void use_class(show&);  
        };  
    }
    
    void name1::use_class(name1::show& h)
    {
    h.a = 1;
    h.b = 2;
    }
    

    主要是:

    name1::show s;
    
    name1::use_class(s);
    

    我不确定为什么你的函数有 void 参数和返回值。

    更新:

    这编译和工作:

    #include "stdafx.h"
    
    namespace name1    
    {   
            class show   
        {   
            int a,b;   
            void accept_data(void);   
            void display_data(void);   
            friend void use_class();  
        };  
    }
    
    void name1::show::accept_data()
    {
        a = 1;
        b = 2;
    }
    
    void name1::show::display_data()
    {
    }
    
    void name1::use_class()
    {
        show s;
    
        s.accept_data();
        s.display_data();
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        name1::use_class();
    
        return 0;
    }
    

    但是,如果我这样写:

    void use_class()
    {
        name1::show s;
    
        s.accept_data();
        s.display_data();
    }
    

    我明白你的错误。确保您的 use_class 属于同一命名空间。

    【讨论】:

    • "虽然有 void 参数和返回值" Andrei 你想用这个传达什么?????
    • @System_Coder:通过 'void accept_data(void);' 接受哪些数据如果参数无效?您的接受/显示功能是否在内部使用 cin/cout?你的'use_class',如果它的参数是无效的,它使用的是什么'show'实例?您是否在“use_class”中创建了“show”实例?你想做什么,因为可能有更好的方法。
    • 我会在 use_class 中创建 show 的实例,当然还有更好的方法可以做到这一点,但我想知道为什么会这样
    • 命名空间 name1 { 类显示 { int a,b;无效接受数据(无效);无效显示数据(无效);朋友无效使用类(无效); };无效使用类(无效); }
    • @System_Coder:因为在一种情况下 use_class 被定义和实现为 name1 命名空间的一部分,而在另一种情况下它是全局命名空间的一部分。您的类定义在 name1 命名空间中有一个 use_class 朋友,而不是在全局命名空间中。
    猜你喜欢
    • 2012-06-11
    • 2012-06-11
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多