朋友的功能和实现

时间:2014-09-23 07:51:38

标签: c++ friend

我遇到了以下代码

class ExDer1 : public ExBase
{
public:
    friend int Der1Fn()
    {
        ....
    }
};

我在这里有点困惑

        friend int Der1Fn()
        {
            //This has an implementation .Why is it a friend then ? since it can access the private/protected variables of the ExDer1  class ?
        }

通常情况下,我希望看到以下内容

friend int Der1Fn(); //No implementation. Indicating that the Der1Fn is a method outside this class

这基本上意味着函数int Der1Fn()将访问类ExDer1的私有变量。然而,这有一个实现。任何人都能解释一下这意味着什么吗?

更新

所以,如果我有以下代码

class ExDer1 : public ExBase
{
public:
    friend int Der1Fn()
    {
        std::cout << "Hello World";
    }
};

int main()
{
    Der1Fn(); // error C3767: 'Der1Fn': candidate function(s) not accessible
    //.....
}

如何调用Der1Fn?

3 个答案:

答案 0 :(得分:2)

您可以在类定义中声明友元函数的主体(就像任何类型的函数一样)。

然而,友元函数遵循所执行的每个函数的相同基本规则:在类定义中声明它(在更改时内联,重新编译所有依赖对象等)是一种不好的做法。

您引用了MSDN示例。他们只是举例说明了如何完成范围界定。函数Der1Fn()在全局命名空间中,而不在ExDer1 :: Der1Fn()中。

您的最新帖子:

类Der1Fn()无法访问ExDer1(它不是类的一部分,它是一个外部函数,将其视为静态)。

但是,在Der1Fn()的主体内部,您可以访问ExDer1类型对象的私有成员变量。

答案 1 :(得分:2)

友元函数(或类)也可以在类外部或内部定义。如果你在里面定义它,你应该在正确的范围内提供匹配的声明,或者发生依赖于参数的查找。

以下示例在逻辑上相同:

示例1:

int Der1Fn();

class ExDer1 : public ExBase
{
public:
    friend int Der1Fn()
    {
        ....
    }
};

示例2(推荐):

int Der1Fn()
{
    ....
}

class ExDer1 : public ExBase
{
public:
    friend int Der1Fn();
};
  

如何调用Der1Fn?

this类似。

答案 2 :(得分:1)

如果某个函数需要访问该类的私有成员,但您不应该成为其成员,那么您将使该函数成为朋友。友元函数可以在类内部或外部实现。

如果在类中声明(并定义)的友元函数,那么它的作用域就在周围的命名空间中,就像你在那里定义它一样; 它只能通过依赖于参数的查找(ADL)找到 - 也就是说,只有使用与其中一个类型相同的命名空间调用它才能找到它参数。

在这种情况下,函数没有参数,因此根本找不到 - 这就是为什么你不能从main或其他任何地方调用它。你需要在类之外以及类中的friend声明中声明函数。

如果它有一个类类型的参数(或在同一名称空间中作用域的其他类型)会更有用;然后在使用该参数类型调用时会找到它:

class ExDer1 : public ExBase
{
public:
    friend int Der1Fn(ExDer1 const &)
    {
        ....
    }
};

int main()
{
    ExDer1 obj;
    Der1Fn(obj);  // Found by ADL
}

在类中定义朋友对于(通常)仅由ADL访问的运算符重载特别有用。