先看代碼
// 友元函數(shù)
// 你是它的好朋友锌妻,那就可以拿私有成員給好朋友
#include <iostream>
using namespace std;
class Person {
private: // 私有的age,外界不能訪問(wèn)
int age = 0;
public:
Person(int age) {
this->age = age;
}
int getAge() {
return this->age;
}
// 定義友元函數(shù) (聲明旬牲,沒(méi)有實(shí)現(xiàn))
friend void updateAge(Person * person, int age);
};
// 友元函數(shù)的實(shí)現(xiàn)仿粹,可以訪問(wèn)所以私有成員
void updateAge(Person* person, int age) {
// 默認(rèn)情況下:不能修改 私有的age
// 誰(shuí)有這個(gè)權(quán)限:友元(拿到所有私有成員)
person->age = age;
}
int main() {
Person person = Person(9);
updateAge(&person, 88);
cout << person.getAge() << endl;
return 0;
}
① 【你是它的好朋友,那就可以拿私有成員給好朋友】
② 【定義友元函數(shù)原茅,然后吭历,友元函數(shù)的實(shí)現(xiàn),可以訪問(wèn)所以私有成員】
一個(gè)相對(duì)正規(guī)的例子
頭文件
#include <iostream>
using namespace std;
#ifndef PIG_H // 你有沒(méi)有這個(gè)宏(Java 宏==常量)
#define PIG_H // 定義這個(gè)宏
class Pig {
private:
int age;
char * name;
public:
// 靜態(tài)成員聲明
static int id;
// 構(gòu)造函數(shù)的聲明系列
Pig();
Pig(char *);
Pig(char *,int);
// 析構(gòu)函數(shù)
~Pig();
// 拷貝構(gòu)造函數(shù)
Pig(const Pig & pig);
// 普通函數(shù) set get
int getAge();
char * getName();
void setAge(int);
void setName(char *);
void showPigInfo() const; // 常量指針常量 只讀
// 靜態(tài)函數(shù)的聲明
static void changeTag(int age);
// 不要這樣干
// void changeTag(int age);
// 友元函數(shù)的聲明
friend void changeAge(Pig * pig, int age);
};
#endif // 關(guān)閉/結(jié)尾
實(shí)現(xiàn)和使用
#include "Pig.h"
// TODO ====================== 下面是 普普通通 常規(guī)操作 對(duì)象::
// 實(shí)現(xiàn)構(gòu)造函數(shù)
Pig::Pig() {
cout << "默認(rèn)構(gòu)造函數(shù)" << endl;
}
Pig::Pig(char * name) {
cout << "1個(gè)參數(shù)構(gòu)造函數(shù)" << endl;
}
Pig::Pig(char * name, int age) {
cout << "2個(gè)參數(shù)構(gòu)造函數(shù)" << endl;
}
// 實(shí)現(xiàn)析構(gòu)函數(shù)
Pig::~Pig() {
cout << "析構(gòu)函數(shù)" << endl;
}
// 實(shí)現(xiàn) 拷貝構(gòu)造函數(shù)
Pig::Pig(const Pig &pig) {
cout << "拷貝構(gòu)造函數(shù)" << endl;
}
int Pig::getAge() {
return this->age;
}
char * Pig::getName() {
return this->name;
}
void Pig::setAge(int age) {
this->age = age;
}
void Pig::setName(char * name) {
this->name = name;
}
void Pig::showPigInfo() const {
} // 常量指針常量 只讀
// =============================== 靜態(tài) 和 友元
// 實(shí)現(xiàn) 靜態(tài)屬性【不需要增加 static關(guān)鍵字】
int Pig::id = 878;
// 實(shí)現(xiàn)靜態(tài)函數(shù)擂橘,【不需要增加 static關(guān)鍵字】
void Pig::changeTag(int age) {
}
// 友元的實(shí)現(xiàn)
// 友元特殊:不需要關(guān)鍵字毒涧,也不需要 對(duì)象:: ,只需要保證 函數(shù)名(參數(shù))
void changeAge(Pig * pig, int age) {
}
延伸思考
// 友元類(lèi) (ImageView 私有成員 可以通過(guò)Class來(lái)訪問(wèn),但是Class操作的native C++代碼)
// ImageView 私有成員 你能訪問(wèn)它的私有成員嗎 Class
#include <iostream>
using namespace std;
class ImageView {
private:
int viewSize;
friend class Class; // 友元類(lèi)
};
// Java每個(gè)類(lèi)贝室,都會(huì)有一個(gè)Class契讲,此Class可以操作 ImageView私有成員(感覺(jué)很神奇)
class Class {
public:
ImageView imageView;
void changeViewSize(int size) {
imageView.viewSize = size;
}
int getViewSize() {
return imageView.viewSize;
}
};
int main() {
Class mImageViewClass;
mImageViewClass.changeViewSize(600);
cout << mImageViewClass.getViewSize() << endl;
return 0;
}
我們操作java代碼,有很多時(shí)候有native的方法聲明滑频,需要下載 JDK native代碼 才能看到捡偏,也是這個(gè)道理。
為什么java 能修改私有屬性峡迷,底層C++ 友元的相關(guān)類(lèi)似操作银伟。