友元函数和友元类

面向对象的基本特征之一是“封装”,在C++类的定义中,我们需要通过访问控制修饰符privatepublic等对使用该类的“用户”能够访问到的数据进行限制。然而,C++由于历史原因(尤其是要兼容C语言)出现了友元的概念,我们可以定义能够自由访问private数据的函数或类。当然,这破坏了面向对象的封装性,不过对于C++来说这种奇怪特性还是有其存在意义的。

友元函数

友元函数可以突破标准OOP风格的访问控制访问类的私有属性,下面是一个例子。

#include <iostream>

class Demo {
private:
  int i;

public:
  Demo(int i) : i(i) {}
  friend void test(Demo *d);
};

void test(Demo *d) { std::cout << d->i << std::endl; }

int main() {
  Demo *d = new Demo(1);
  test(d);
  delete d;
  return 0;
}

Demo1.i是私有的成员变量,但是我们声明了友元函数后,这个函数就能自由使用Demo1类中的所有数据了。

友元类

下面代码中,定义了Demo1的友元类Demo2,Demo2中就能自由使用Demo1类中的private成员变量了。

#include <iostream>

class Demo1;
class Demo2;

class Demo1 {
private:
  int i;

public:
  Demo1(int i) : i(i) {}

  void showI() { std::cout << this->i << std::endl; }

  friend class Demo2;
};

class Demo2 {
public:
  Demo1 *d;
  Demo2(Demo1 *d) {
    this->d = d;
    this->d->i = 2;
  }
};

int main() {
  Demo1 *d1 = new Demo1(1);
  Demo2 *d2 = new Demo2(d1);

  d1->showI();

  delete d1;
  delete d2;
  return 0;
}

友元类的的概念和友元函数相同,同样是使用friend关键字进行定义。

友元的性质

友元的使用遵循以下几个特性:

  • 友元不能继承
  • 友元是单向的,A是B的友元,不代表B是A的友元
  • 友元不具有传递性,B是A的友元,C是B的友元,不代表C是A的友元,除非A中声明C是
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap