【问题标题】:Is there any difference if we define friend function inside or outside of class如果我们在类内部或外部定义友元函数有什么区别吗
【发布时间】:2013-11-21 07:14:28
【问题描述】:

在类内定义友元函数与在类内声明和在类外定义有什么区别。还有为什么可以将定义放在类中,因为友元函数不是类的成员。

【问题讨论】:

标签: c++


【解决方案1】:

类内定义的友元函数只有在从类外调用时才能通过 ADL 查找。即使没有 ADL,也可以找到在类之外定义的函数。

【讨论】:

  • +1 表示 Joachim 选择的引用,这可能是最重要的区别。
  • 刚刚遇到这个问题。在我的例子中,这是一个 operator== 定义为类中的朋友,当它的两个参数都需要隐式转换时,编译器找不到它......
  • 其实我还是不太明白,所以我创建了一个单独的问题:stackoverflow.com/questions/52067502/…
  • @anxieux 隐式转换可能是好是坏,this answer 也提供了更详细的视图。
  • @Wormer,是的,谢谢,您引用的答案来自我接受的问题:-)
【解决方案2】:

只要在类中声明友元函数(它必须是),它的声明在哪里都没有关系。

此外,在类中定义 friend 函数也会隐式生成函数 inline

另外(来自 C++11 规范,§11.3/7):

类中定义的友元函数在 定义它的类。类外定义的友元函数不是

【讨论】:

    【解决方案3】:

    以下关于会员访问的内容有微妙的含义。

    C++11 §11.4/5

    类中定义的友元函数在 定义它的类。在外部定义的友元函数 类不是 (3.4.1)。

    自 C++17 §14.3/7 起仍存在

    这样的函数隐含地是一个内联函数 (10.1.6)。一个朋友 类中定义的函数在类的(词法)范围内 它是定义的。在类外定义的友元函数是 不是 (6.4.1)。

    考虑来自cppreference [Friend 函数定义] 的简化示例,其中f1 查找类静态成员,f2 查找全局变量。

    int i = 3;
    struct X {
        friend void f1(int x) {
            i = x; // finds and modifies X::i
        }
        friend inline void f2(int);
        static const int i = 2;
    };
    
    inline void f2(int x) {
        i = x; // finds and modifies ::i
    }
    

    当然这不会影响友元功能的设计设计。选择之间的主要考虑因素是名称查找的差异,正如the other 答案中已经提到的那样。不要忘记f2 的内联以匹配默认隐含的f1

    【讨论】:

      【解决方案4】:

      一个函数可以定义在一个类的友元声明中,如果并且 仅当类是非本地类时,函数名是 不合格,并且该函数具有命名空间范围。这样的功能是 隐式内联。类中定义的友元函数在 定义它的类的(词法)范围。朋友功能 类外定义的不是。

      C++11,[class.friend],¶6-7

      【讨论】:

        【解决方案5】:

        如果你在类里面定义它是内联的,如果它在外面就不是。

        【讨论】:

        • 这是错误的。 Friend 方法总是 inline
        【解决方案6】:

        在类中定义友元函数是不合适的

        我们使用友元函数将类的私有成员的访问权限授予函数。

        如果我们在类中定义友元函数,那么它就成为类的数据成员,我们知道自己类的数据成员可以访问其私有成员。

        所以如果你真的想在 C++ 中使用友元概念,那么在私有类之外声明它。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-17
        • 2016-04-29
        • 2014-01-24
        • 2015-02-10
        • 1970-01-01
        • 2016-11-13
        相关资源
        最近更新 更多