友元 流插入流提取

如何支持自定义流插入,流提取

流插入<<,流提取>>

filename already exists, renamed

  1. 由于函数重载实现了”自动识别”类型。
  2. 直接可以支持内置类型,因为库内部已经将其实现了

如何让自定义类型支持流插入和流提取

由于操作符重载的时候,对于二元函数来说,规定第一个参数,和第二个参数分别对应左操作数和右操作数

而对于我们习惯的来说,cout始终为左操作数。

如何让它支持习惯的写法呢?

  1. 不可以将其写为成员函数,因为Date对象会默认占用第一个参数,就是作了左操作数。

  2. 将其写为全局,这样就不存在抢占。

  3. 为了解决全局函数访问私有成员的问题,我们需要添加友元函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*如果不进行其他处理,cout的操作会变得不自然*/
    #include <iostream>

    class MyClass {
    public:
    int value;
    MyClass(int v) : value(v) {}

    // 重载<<操作符
    std::ostream& operator<<(std::ostream& os) {
    os << this->value;
    return os;
    }
    };

    int main() {
    MyClass obj(42);
    std::cout << obj.value << std::endl;
    return 0;
    }

1. 重载 << 操作符(流插入操作符)

流插入操作符 << 通常用于输出对象的数据。重载 << 时,通常作为友元函数(friend function)来实现,以便访问私有成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

class MyClass {
private:
int value;
public:
MyClass(int v) : value(v) {}

// 友元函数,用于重载 << 操作符
friend std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
os << "MyClass value: " << obj.value;
return os;
}
};

int main() {
MyClass obj(42);
std::cout << obj << std::endl; // 输出:MyClass value: 42
return 0;
}

2. 重载 >> 操作符(流提取操作符)

流提取操作符 >> 通常用于从输入流中读取数据到对象。重载 >> 时,也通常作为友元函数来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

class MyClass {
private:
int value;
public:
MyClass() : value(0) {}

// 友元函数,用于重载 >> 操作符
friend std::istream& operator>>(std::istream& is, MyClass& obj) {
is >> obj.value;
return is;
}

void print() const {
std::cout << "MyClass value: " << value << std::endl;
}
};

int main() {
MyClass obj;
std::cin >> obj; // 假设输入:42
obj.print(); // 输出:MyClass value: 42
return 0;
}

友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多

友元分为:友元函数友元类

友元函数

友元函数可以直接访问类的私有成员

它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字

  1. 友元函数可访问类的私有和保护成员,但不是类的成员函数。
  2. 友元函数不能用const修饰友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
  3. 一个函数可以是多个类的友元函数。
  4. 友元函数的调用与普通函数的调用原理相同。

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

注意:

  1. 友元关系是单向的,不具有交换性
  2. 友元关系不能传递
  3. 友元关系不能继承

友元 流插入流提取
https://weihehe.top/2024/07/04/友元/
作者
weihehe
发布于
2024年7月4日
许可协议