友元

友元的作用:在不改变数据安全性的前提下,使得类外部的函数或者另一个类能够访问该类中的私有数据成员

三种形式:

(1)友元函数

(2)友元成员

(3)友元类

一、友元函数

定义:将一个不属于任何类的普通函数定义为当前类的友元,成为当前类的友元函数

原型声明:friend 函数返回类型 函数名(形式参数表)

例如:我们需要一个Equal函数来比较两个Date类的对象是否相等

  Date.h

#ifndef DATE_H
#define DATE_H


class Date
{
private:
    int year;
    int month;
    int day;
public:
    Date(int ,int ,int );
    ~Date();
    int GetYear();
    int GetMonth();
    int GetDay();
    friend bool Equal(Date &,Date &);///将在Equal函数声明为Date的友元函数
};

#endif // DATE_H

Date.cpp

#include "Date.h"

Date::Date(int y,int m,int d)
{
    year=y;
    month=m;
    day=d;
}

Date::~Date()
{
    //dtor
}
int Date::GetYear()///在类外实现的时候竟然又忘记了加 类名:: ,还是练得少啊
{
    return year;
}
int Date::GetMonth()
{
    return month;
}
int Date::GetDay()
{
    return day;
}

main.cpp

#include <iostream>
#include"Date.h"
using namespace std;

bool Equal(Date &DateA,Date &DateB)
{
    ///因为Equal已经声明为Date类的友元函数,Date类的对象不需要通过成员函数就能直接访问数据成员
    if(DateA.year==DateB.year&&DateA.month==DateB.month&&DateA.day==DateB.day)
    return true;
    else return false;
}
int main()
{
    Date YourBirthday(1990,10,7);
    Date MyBirthday(1990,10,7);
    if(Equal(YourBirthday,MyBirthday))///比较两个对象是否相同
        cout<<"Birthday is the same"<<endl;
    else
        cout<<"Birthday is not the same"<<endl;
    return 0;
}

 

二、友元成员函数

定义:一个类的成员函数作为另一个类的友元,成为另一个类的友元成员。

作用:不仅可以访问自己所在类的数据成员,也可以访问friend声明语句所在类的所有成员

例子:将Date类的成员函数Display声明为Student类的友元函数(同时说明了类的声明,类的实现,main函数可以写在同一个.cpp文件中)

#include<iostream>
#include<cstring>
using namespace std;
class Student;  ///向前引用,为什么不同通过先后定义的顺序来解决呢?因为Date类和Student类你中有我,我中有你
class Date
{
private:
    int year;
    int month;
    int day;
public:
    Date(int y=2007,int m=1,int d=1);
    void Display(const Student &);///成员函数,形式参数为Student的对象的引用
};
class Student
{
private:
    char *specialty;
public:
    Student(char *pSpec);
    ~Student();
    friend void Date::Display(const Student &);///将Date类中的成员函数Display声明为Student类的友元函数
};
Date::Date(int y,int m,int d)
{
    year=y;
    month=m;
    day=d;
    cout<<"Constructor Called"<<endl;
}
void Date::Display(const Student &stu)
{
    cout<<stu.specialty<<endl;
    cout<<year<<"-"<<month<<"-"<<day<<endl;///因为Date::Display为Student的友元函数,所以可直接使用Student中的数据成员
}
Student::Student(char *pSpec)///pSpec接收 定义对象时传的实参的地址
{
    if(pSpec)///数据成员的赋值
    {
        specialty=new char[strlen(pSpec)+1];
        strcpy(specialty,pSpec);
    }
    else specialty=0;
}
Student::~Student()///包含 指向动态存储空间的指针类型,所以析构函数要自己写啦
{
    if(specialty)
        delete []specialty;
}
int main()
{
    Student zhang("computer");
    Date Birthday(1990,10,17);
    Birthday.Display(zhang);
    return 0;
}

三、友元类

定义:将一个类声明为另一个类的友元。

作用:若一个类被声明为另一个类的友元,则该类中的所有成员函数都是另一个类的友元成员,都可以访问另一个类的所有成员。

例子:将Student类作为Date的友元类,验证Student类中的成员函数可以直接调用Date类中的数据成员

#include<iostream>
#include<cstring>
using namespace std;
class Student; ///向前引用
class Date
{
private:
    int year;
    int month;
    int day;
public:
    Date(int ,int ,int);
    void Display();  
    friend Student;
};

class Student
{
private:
    char *specialty;///只要看到char指针,不用想,肯定指向动态存储空间
    char *name;
public:
    Student(char *pn,char *pSpec);
    ~Student();
    void Display(Date &);///Date中有一个Display,Student 类中也有一个Display,虽然名字相同的,但执行的功能却大不相同
};

Date::Date(int y,int m,int d):year(y),month(m),day(d)///另一种赋值方式
{}

void Date::Display()
{
    cout<<year<<"-"<<month<<"-"<<day<<endl;
}
Student::Student(char *pn,char *pSpec)
{
    if(pSpec)///如果pSpec指向的内容不为空,说明它指向某个空间
    {
        specialty=new char[strlen(pSpec)+1];///申请与pSpec指向的空间大小相同的 动态存储空间,并返回首地址
        strcpy(specialty,pSpec);///将pSpec指向的动态存储空间的内容 赋给 specialty指向的动态存储空间
    }
    else
        specialty=0;
    if(pn)
    {
        name=new char[strlen(pn)+1];
        strcpy(name,pn);
    }
    else name=0;
}
Student::~Student()
{
    if(specialty)///指向动态存储空间
        delete []specialty;///释放specialty所指的动态存储空间
    if(name)
        delete []name;
}
void Student::Display(Date &obj)
{
    cout<<name<<endl;
    cout<<specialty<<endl;
    obj.Display();
    cout<<"Date's another format is:";
    cout<<obj.month<<"-"<<obj.day<<"-"<<obj.year<<endl;///因为Student为Date的友元类,所以Student的成员函数Display中可以直接调用Date中的数据成员
}
 int main()
 {
     Student boy("zhang","computer");
     Date birthday(1990,10,17);
     boy.Display(birthday);
     return 0;
 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值