文章目录
- 4 类和对象
- 4.4 友元
- 4.4.1 全局函数做友元
- 4.4.2 类做友元
- 4.4.3 成员函数做友元
- 4.4.4 Date类作为person类的友元
4 类和对象
4.4 友元
生活中你的家有客厅(Public),有你的卧室(Private)。
客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去。
但是呢,你也可以允许你的好闺蜜好基友进去。
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。
友元的目的就是让一个函数或者类 访问另一个类中私有成员。
友元的关键字为 friend
友元的三种实现
- 全局函数做友元
- 类做友元
- 成员函数做友元
4.4.1 全局函数做友元
例4.4.1
#include <iostream>using namespace std;class Building
{//告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容friend void goodGay(Building * building);public:Building(){this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";}public:string m_SittingRoom; //客厅private:string m_BedRoom; //卧室
};void goodGay(Building * building)
{cout << "好基友正在访问: " << building->m_SittingRoom << endl;cout << "好基友正在访问: " << building->m_BedRoom << endl;
}void test01()
{Building b;goodGay(&b);
}int main()
{test01();return 0;
}
结果如下:
好基友正在访问: 客厅
好基友正在访问: 卧室Process returned 0 (0x0) execution time : 0.032 s
Press any key to continue.
4.4.2 类做友元
例4.4.2
#include <iostream>using namespace std;class Building;class goodGay
{
public:goodGay();void visit();private:Building *building;
};class Building
{//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容friend class goodGay;public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";
}goodGay::goodGay()
{building = new Building;
}void goodGay::visit()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;cout << "好基友正在访问" << building->m_BedRoom << endl;
}void test01()
{goodGay gg;gg.visit();}int main()
{test01();return 0;
}
结果如下:
好基友正在访问客厅
好基友正在访问卧室Process returned 0 (0x0) execution time : 0.009 s
Press any key to continue.
4.4.3 成员函数做友元
例4.4.3
#include <iostream>using namespace std;class Building;class goodGay
{
public:goodGay();void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容void visit2();private:Building *building;
};class Building
{//告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容friend void goodGay::visit();public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this->m_SittingRoom = "客厅";this->m_BedRoom = "卧室";
}goodGay::goodGay()
{building = new Building;
}void goodGay::visit()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;cout << "好基友正在访问" << building->m_BedRoom << endl;
}void goodGay::visit2()
{cout << "好基友正在访问" << building->m_SittingRoom << endl;//cout << "好基友正在访问" << building->m_BedRoom << endl;
}void test01()
{goodGay gg;gg.visit();}int main()
{test01();return 0;
}
结果如下:
好基友正在访问客厅
好基友正在访问卧室Process returned 0 (0x0) execution time : 0.013 s
Press any key to continue.
4.4.4 Date类作为person类的友元
题目如下:
上机实验三,沿用上机实验二的Person类,设计一个Date类,并在Person中增加Date的对象Birthday(has a)。将类定义(class definition)写在 Person.h 及 Date.h 中。 将成员函数(member function)写在 person.cpp 及 Date.cpp中。
编程一個主程式(main) 在主程序中建构两个 Person 对象,一个用全预设值,另一个给定所有的参数。 测试所有的功能,打印(print())对象的内容。
Date
<<constructor>>+Date(y : int = 0, m : int = 0,d : int = 0)
<<destructor>>+~Date()
+setYear(y : int) : void
+setMonth(m : int) : void
+setDay(d : int) : void
+getYear() : int
+getMonth() : int
+getDay() : int
+print() : void
-Year : int
-Month : int
-Day : int
Person
-Name : string
-ID : int
-Address : string
-Birthday: Date
<<constructor>> +Person(name : string = “”, id : int =
0, address : string = “”, Date = Date())
<<desctructor>> +~Person()
+setName(name : string)
+getName() : string
+setID(id : int)
+getID() : int
+setAddress(address : string)
+getAddress() : string
+setBirthday(d : Date)
+getBirthday() : Date
+print() : void
解答如下:
main.cpp
#include <iostream>
#include "Person.h"
using namespace std;int main()
{Person myPerson;// Person myPerson("S.M.Wang", 070145, "莲花路200号");cout << "请输入姓名:" ;string name;cin >> name;cout << "请输入ID:" ;int id;cin >> id;cout << "请输入住址:" ;string address;cin >> address;Date myDate;cout << "请输入生日年:" ;int year;cin >> year;cout << "请输入生日月:" ;int month;cin >> month;cout << "请输入生日天:" ;int day;cin >> day;myPerson.setName(name);myPerson.setID(id);myPerson.setAddress(address);myDate.setYear(year);myDate.setMonth(month);myDate.setDay(day);myPerson.setBirthday(myDate); // 调用的形参为类myPerson.print();return 0;
}
Person.h
#include <iostream>
#include "Date.h"
using namespace std;class Person
{
public:Person();Person(string name, int id, string address);~Person();void setPerson(string name, int id, string address);void setName(string name);void setID(int id);void setAddress(string address);void setBirthday(Date d);string getName();int getID();string getAddress();Date getBirthday();void print(); // outPutResult
private:string Name;int ID;string Address;Date Birthday;
};
Date.h
#include <iostream>using namespace std;class Date
{friend class Person;
public:Date();Date(int y, int m, int d);~Date();void setYear(int y);void setMonth(int m);void setDay(int d);int getYear();int getMonth();int getDay();void print();
private:int Year;int Month;int Day;};
Person.cpp
#include "Person.h"
#include <iostream>
using namespace std;Person::Person()
{Name = "S.M.Wang";ID = 070145;Address = "莲花路200号";
}Person::Person(string name, int id, string address)
{setPerson(name, id, address);
}Person::~Person()
{//cout << "object Destructor is called" << endl;
}void Person::setPerson(string name, int id, string address)
{Name = name;ID = id;Address = address;
}void Person::setName(string name)
{Name = name;
}void Person::setID(int id)
{ID = id;
}void Person::setAddress(string address)
{Address = address;
}string Person::getName()
{return Name;
}int Person::getID()
{return ID;
}string Person::getAddress()
{return Address;
}void Person::setBirthday(Date d) // 调用的形参是类
{Birthday = d;
}Date Person::getBirthday() // 返回的是类
{return Birthday;
}void Person::print()
{cout << "Name:" << getName() << endl;cout << "ID:" << getID() << endl;cout << "Address:" << getAddress() << endl;cout << "Birthday:" << getBirthday().getYear(); // getBirthday()返回的是类,再调用类中的子函数满足cout的返回值。cout << " " << getBirthday().getMonth();cout << " " << getBirthday().getDay() << endl;
}
Date.cpp
#include "Date.h"
#include <iostream>
using namespace std;Date::Date()
{Year = 0;Month = 0;Day = 0;
}Date::Date(int year, int month, int day)
{setYear(year);setMonth(month);setDay(day);
}Date::~Date()
{//cout << "object Destructor is called" << endl;
}void Date::setYear(int year)
{Year = year;
}void Date::setMonth(int month)
{Month = month;
}void Date::setDay(int day)
{Day = day;
}int Date::getYear()
{return Year;
}int Date::getMonth()
{return Month;
}int Date::getDay()
{return Day;
}void Date::print()
{cout << "Year :" << getYear() << endl;cout << "Month :" << getMonth() << endl;cout << "Day :" << getDay() << endl;
}
结果如下:
请输入姓名:S.M.Wang
请输入ID:070145
请输入住址:莲花路200号
请输入生日年:2000
请输入生日月:1
请输入生日天:1
Name:S.M.Wang
ID:70145
Address:莲花路200号
Birthday:2000 1 1Process returned 0 (0x0) execution time : 49.737 s
Press any key to continue.