C++ 面向对象-友元

本文最后更新于:2022年4月22日 上午

全局函数做友元、友元类、成员函数做友元

友元可以让类外的作用域可以访问 class 中的私有成员(private)

全局函数做友元

使指定的全局函数可以访问 class 中的私有成员

用法:在类的最前面 加上函数的声明并在 加上 friend 关键字

class Test5 {
// 使用 friend 修饰为 友元,既可以访问类的属性
 friend void Test5Func(Test5* t);

private:
  string name;

public:
  string getName() {
    return this->name;
  }
};

void Test5Func(Test5* t) {
  // 设置私有成员
  t->name = "小明";
  // 获取私有成员
  cout << t->name << endl;
}

void test5() {
  Test5 t5;
  Test5Func(&t5);

  cout << "name:" << t5.getName() << endl;
}

// ...

test5();

输出

小明
name:小明

友元类

// 假设客厅是公共的,卧室是私人的,但是好朋友可以访问卧室,就可以使用 firend 技术实现
class Test66;

class Test6 {

  friend Test66;

public: 
  string livingRoom;  // 客厅
  
  // 构造函数赋初始值
  Test6();

private:
  string bedroom;    // 卧室
};

// 声明与实现分开编写
Test6::Test6(){
  livingRoom = "客厅";
  bedroom = "卧室";
}


class Test66 {

public:
  Test6* room;

  Test66();

  void visit();
};

Test66::Test66() {
  room = new Test6();
};


void Test66::visit() {
  // 访问公共成员
  cout << "访问:" << room->livingRoom << endl;
  // 访问私有成员
  cout << "访问:" << room->bedroom << endl;
}

// 测试
void test6() {
  Test66 t;
  t.visit();
}

// ...
test6();

输出

访问:客厅
访问:卧室

成员函数做友元

// 这两个顺序不可颠倒,否则会报错
class Test77;
class Test7 {

public:
  Test77* room;

  Test7();
  void visit();
};

class Test77 {

  friend void Test7::visit();

public:
  string livingRoom;  // 客厅

  // 构造函数赋初始值
  Test77();

private:
  string bedroom;    // 卧室
};

Test77::Test77() {
  livingRoom = "客厅";
  bedroom = "卧室";
}


Test7::Test7() {
  room = new Test77;
}

void Test7::visit() {
  // 访问公共成员
  cout << "访问:" << room->livingRoom << endl;
  // 访问私有成员
  cout << "访问:" << room->bedroom << endl;
}


void test7() {
  Test7 t;
  t.visit();
}

输出

访问:客厅
访问:卧室

总结

通过 友元 (friend) 就可以在类外访问类的私有成员。