C++ 友元(friend)


目录

友元(friend)

全局函数做友元函数

类做友元

成员函数做友元

总结


推荐:c++成员运算符重载和友元运算符重载的比较(以++,--运算符为例)https://blog.csdn.net/ayangya/article/details/78901294 

友元(friend)

C++中友元(友元函数和友元类)的用法和功能:https://blog.csdn.net/adriano119/article/details/5914443

C++友元函数和友元类用法详解:https://blog.csdn.net/fanyun_01/article/details/79122916

 类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。

但是,有时候需要在类的外部访问类的私有成员

解决方法是使用友元函数,友元函数是一种特权函数,C++允许这个特权函数访问私有成员。

使用友元要务必注意,因为会破坏类的数据隐藏

全局函数做友元函数

  1. 在类外声明函数原型(因为是全局函数) 【 返回值 函数名 (形式参数); 】
  2. 在类内加上friend关键字,再次声明函数原型【 friend 返回值 函数名 (形式参数); 】
  3. 在cpp中进行函数定义,友元函数可以访问类的私有变量
class Time : public QMainWindow
{
public:
    Time();
    ~Time();

    int min;
private:
    int second;
};
void Frifunction(Time * time);
Time::Time():
    min(10),
    second(20)
{
    qDebug()<<"进入Time构造函数";

}
Time::~Time()
{
    qDebug()<<"进入Time析构函数";
}
void Frifunction(Time * time)
{
    qDebug()<<time->min<<time->second;
}

没有声明友元的情况下,编译器报错

second是私有成员变量,只要成员函数可以访问,如果全局函数想访问,需要在类中,加friend关键字,并且再次声明

class Time : public QMainWindow
{
public:
    Time();
    ~Time();

    int min;
    
    friend void Frifunction(Time * time);//2,在类内加上friend关键字,再次声明函数原型

private:
    int second;
};
void Frifunction(Time * time);//1,在类外声明函数原型(因为是全局函数)
Time::Time():
    min(10),
    second(20)
{
    qDebug()<<"进入Time构造函数";

}
Time::~Time()
{
    qDebug()<<"进入Time析构函数";
}
void Frifunction(Time * time)
{
    qDebug()<<time->min<<time->second;
}

 此时程序就不会报错了

需要在类中增加一句:friend 返回值 函数名(形式参数);

Time t;
Frifunction(&t);

因为在默认构造函数中已经初始化,程序输出如下:

友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
友元函数的调用与一般函数的调用方式和原理一致。 

 

类做友元

  1. A类想要访问B类中的所有成员变量
  2. 在B类中声明:【friend class A】

在想被访问的类中添加friend声明

.h 

class PinkFloyd
{
public:
    PinkFloyd();
    ~PinkFloyd();

    int music;
    void JustTest();
private:
    int Rock;
};

class Time
{
public:
    Time();
    ~Time();
    int min;
private:
    int sec;
};

.cpp 

PinkFloyd::PinkFloyd():
    music(1968),
    Rock(2020)
{
    qDebug()<<"进入PinkFloyd构造函数";
}

PinkFloyd::~PinkFloyd()
{
    qDebug()<<"进入PinkFloyd析构函数";
}
void PinkFloyd::JustTest()
{
    qDebug()<<"进入JustTest";
    Time T;
    qDebug()<<"T.sec"<<T.sec;
}
Time::Time():
    min(20),
    sec(20)
{
    qDebug()<<"进入Time构造函数";

}

Time::~Time()
{
    qDebug()<<"进入Time构造函数";

}

 程序会报错:

目前是PinkFloyd所在的类想要访问Time中的私有变量,所有,在Time中增加一句声明

class Time
{
public:
    Time();
    ~Time();
    friend class PinkFloyd;//友元类的声明
    int min;
private:
    int sec;
};

成员函数做友元

  1. A类成员函数想访问B类私有变量
  2. 在B类中声明:【friend 返回值 所在类名::函数名 (形式参数)】

.h 

class PinkFloyd
{
public:
    PinkFloyd();
    ~PinkFloyd();

    int music;
    void JustTest();
    void OnlyTest();//只让onlytest函数能访问Time中的成员变量
private:
    int Rock;
};

class Time
{
    
public:
    Time();
    ~Time();

    int min;

    friend void PinkFloyd::OnlyTest();//成员函数做友元函数
private:
    int sec;
};

.cpp 

void PinkFloyd::OnlyTest()
{
    qDebug()<<"进入OnlyTest";
    Time T;
    qDebug()<<"T.sec"<<T.sec;

}

总结

使用友元类时注意:

  1. 友元关系不能被继承。 
  2. 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
  3. 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的

 

同样,友元函数没有this指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值