如何正确访问好友功能

How to access friend functions correctly?

本文关键字:功能 好友 访问 何正确      更新时间:2023-10-16

我正在尝试访问一个朋友的方法,定义如下。我有4个文件。两个标题:

标题a.h:

#include "b.h"
class A
{
public:
    A();
    ~A();
    void testStuff(int i);
};

标题b.h:

#include "a.h"
class A;
class B
{
    friend class A;
public:
    B();
    ~B();
    friend void doStuff(int i);
};

和两个包括一些代码,a.cpp:

#include "a.h"
void A::testStuff()
{
    B b {B()};
    b->doStuff(1);
}

b.cpp:

#include "b.h"
void B::doStuff(int i)
{
    m_stuff = i;
}

如果我删除关键字friend一切工作正常。但是,如果我声明doStuff()为友元,我得到以下错误:

error: ‘class B’ has no member named ‘doStuff’

我试着遵循这个教程。我错过了什么?

您对friend功能的理解是错误的如果将函数friend声明给另一个类,则意味着friend函数可以访问该类的私有成员,而不意味着friend函数成为类成员

这里的doStaff()friendB,而不是B的成员。但是你在B的对象上使用它,因此编译器说它不是该类的成员。friend允许doStaff访问Bprivate成员。

你所遵循的教程清楚地说明了这一点。duplicate()方法是Rectangle的友元,因此它可以访问private成员widthheight,但duplicate()没有被用作Rectangle的类方法。

总之,你的问题是错误的。您可以像访问任何自由的(非类方法)函数一样访问friend函数。问题是friend函数如何访问它是友元的类的成员,如前所述,它可以访问该类中的所有内容,这就是使用友元函数的动机,即将类的私有成员的访问权授予外部人员。

类似地,friend类可以访问它是友类的所有内容。

所以对于你的问题,要么你从doStaff中删除friend,使其成为B的成员。但我猜你的意图是使用friend方法,在这种情况下,你可以做以下操作:

void doStuff(B b, int i)
{
  b.m_stuff = i; // it is friend function of B, so can access m_staff
}

或者你可以让doStaff()成为A的成员然后你可以写

class A{
  //other members
  void doStaff(B& b, int i){ b.m_staff=i;}
void A::testStuff() {
  B b {B()};
  doStuff(b,1); //although u can just write "b.m_staff = 1;" right here
}

在自己的类中将方法声明为"友类"是没有意义的。因此,像

这样的友元声明
friend void doStuff(int i);
类B中的

实际上并没有声明类B的成员函数(它是一个家族,你不需要把它设为友元),它声明了一个名为doStuff的全局函数。你可以写

friend void A::doStuff(int i);

意思是"如果在某个地方有一个名为a的类,并且它有一个名为doStuff的带int形参的成员,那么该成员函数是友元"。你写的是"如果在某个地方有一个全局函数doStuff (int i),那么这个函数就是朋友"。

所以你没有在你的类中声明B:doStuff (int i),并且实现这个函数非常明显地给出了一个错误。

如果你想让A::testStuff()被允许调用doStuff,你应该添加类B:

friend void A::testStuff ();

您将doStuff()声明为类B的成员,当您执行"void B::doStuff(int i)"时,但是friend关键字适用于非成员函数。它基本上是为了使非类成员的函数可以访问该类的私有成员。

顺便说一句,B将类A声明为友类,这意味着在A中声明的函数可以访问类B中的私有成员。

可以看到,声明友元类和友元函数是有区别的。