核心要点速览
- 友元:打破封装,允许外部函数 / 类访问类的私有 / 保护成员(分友元函数、友元类、友元成员函数)
- 运算符重载:自定义类型的运算规则,不可重载 6 个运算符,支持成员函数 / 友元函数两种形式
- 特殊重载:赋值运算符=只能作为成员函数;
<</>>需作为友元函数
一、友元:打破封装的特殊访问机制
友元的核心是 “让外部实体获得类的特殊访问权限”,可访问私有(private)和保护(protected)成员,代价是削弱封装性。
1. 友元的种类
(1)友元函数
-
声明方式:类内用
friend声明,定义可在类外(非成员函数,无this指针)。 -
示例:
class A { private: int num = 10; // 友元函数声明 friend void printA(A& obj); }; // 友元函数定义(类外),可直接访问私有成员 void printA(A& obj) { cout << obj.num << endl; // 合法:访问A的private成员 } -
关键:访问类成员时需显式传递对象参数(无
this指针)。
(2)友元类
- 声明方式:类内用
friend class 类名;,目标类的所有成员函数均可访问当前类私有成员。 - 示例:
class A { private: int num = 10; friend class B; // 声明B为友元类 }; class B { public: void accessA(A& obj) { cout << obj.num << endl; // 合法:B的成员函数访问A的private成员 } };
(3)友元成员函数
- 声明方式:指定类的某个成员函数作为友元,更精准控制访问权限。
- 示例:
class B; // 前置声明 class A { private: int num = 10; // 声明B的show()函数为友元 friend void B::show(A& obj); }; class B { public: void show(A& obj); // 成员函数声明 }; // B的show()函数定义,可访问A的private成员 void B::show(A& obj) { cout << obj.num << endl; }
2. 友元的特性
- 不可传递性:A 是 B 的友元,B 是 C 的友元,不代表 A 是 C 的友元。
- 单向性:A 声明 B 为友元,仅 B 能访问 A,A 不能访问 B。
- 声明位置无关:友元声明可放在类的 public/private/protected 任意区域,效果一致。
二、运算符重载:自定义类型的运算规则
运算符重载是赋予自定义类型(类 / 结构体)运算符(如+、==)的运算能力,语法为返回类型 operator运算符(参数列表)。
1. 重载规则
- 不可重载的 6 个运算符(固定):
.(成员访问)、.*(成员指针访问)、::(作用域解析)、sizeof(大小计算)、?:(三目运算符)、typeid(类型信息)。
- 不可改变的特性:运算符的优先级、结合性、操作数个数。
- 必须包含至少一个自定义类型操作数(避免重载内置类型运算)。
2. 两种重载形式
(1)成员函数重载
- 核心:左侧操作数为当前类对象(隐含
this指针),参数列表只需传入右侧操作数。 - 适用场景:左侧操作数是当前类对象(如
a + b,a 是当前类对象)。 - 示例(重载
+):class Point { private: int x, y; public: Point(int x=0, int y=0) : x(x), y(y) {} // 成员函数重载+:this指向左侧操作数 Point operator+(const Point& rhs) { return Point(x + rhs.x, y + rhs.y); } }; // 调用:左侧a是this指针指向的对象 Point a(1,2), b(3,4); Point c = a + b; // 等价于a.operator+(b)
(2)友元函数重载
- 核心:无
this指针,需显式传入所有操作数(左侧 + 右侧)。 - 适用场景:左侧操作数不是当前类对象(如
cout << a,左侧是ostream对象)。 - 示例(重载
<<,输出自定义类型):class Point { private: int x, y; public: Point(int x=0, int y=0) : x(x), y(y) {} // 友元函数重载<<:需访问私有成员,且左侧是ostream friend ostream& operator<<(ostream& os, const Point& p) { os << "(" << p.x << "," << p.y << ")"; return os; // 支持链式输出(cout << a << b) } }; // 调用:os=cout,p=a Point a(1,2); cout << a; // 等价于operator<<(cout, a),输出(1,2)
3. 特殊重载:赋值运算符=
- 规则:只能作为成员函数(编译器默认生成,执行浅拷贝)。
- 深拷贝需求:当类包含动态资源(如指针)时,需手动重写,避免双重释放。
- 示例(深拷贝赋值运算符):
class String { private: char* str; public: // 赋值运算符重载(成员函数) String& operator=(const String& other) { if (this == &other) return *this; // 处理自我赋值 delete[] str; // 释放当前资源 // 深拷贝:重新分配内存 str = new char[strlen(other.str) + 1]; strcpy(str, other.str); return *this; // 支持链式赋值(a = b = c) } };

291

被折叠的 条评论
为什么被折叠?



