C++ 运算符重载笔记

Search for a command to run...

No comments yet. Be the first to comment.
一、有序对和笛卡尔积 1、有序对(序偶):由两个元素 x 和 y 按照确定顺序排列组成的二元组,记作⟨x, y⟩ 2、笛卡尔积:以 A 中元素为第一元、B 中元素为第二元,构造所有有序对⟨x,y⟩; 由全部这类有序对构成的集合,称为 A 与 B 的笛卡尔积,记作 AXB 例题: 已知 A={a,b}, B={0,1,2},求笛卡尔积 A × B、B × A A × B(前元取自 A,后元取自 B

1、集合的概念 N元子集:含有n个元素的子集叫做N元子集. 例题:已知集合 A={1,2,3},按元素个数对 A 的所有子集分类 0元子集:∅ 1元子集:{1}, {2}, {3} 2 元子集:{1,2}, {1,3}, {2,3} 3 元子集:{1,2,3} 幂集:设 A 为集合,由 A 的全部子集构成的集合称为 A 的幂集,记作P(A). 例题:A={1,2,3},求A的幂集 答案:P

一、基本元件 元件 符号 说明 例子 个体词 a, b, c... 代表具体对象(常元) a:小明 个体变元 x, y, z... 代表任意对象 x 表示论域中任一元素 谓词 P(x), Q(x,y)... 表示性质或关系 P(x):x是学生; L(x,y):x喜欢y 量词 ∀, ∃ 修饰个体范围 ∀x(所有x); ∃x(存在x) 连接词 ¬, ∧, ∨, →, ↔ 命

本质是"逻辑推导游戏",给定几个前提,用固定规则一步步推出结论。套路固定,背下规则就能拿分。 一、核心推理规则公式: 假言推理(MP)A→B, A ⇒ B肯定前件→肯定后件拒取式(MT)A→B, ¬B ⇒ ¬A否定后件→否定前件假言三段论(HS)A→B, B→C ⇒ A→C蕴含传递析取三段论(DS)A∨B, ¬A ⇒ B否定一边得另一边附加律A ⇒ A∨B或上一个随便什么化简律A∧B ⇒ A (或

定义:S是一个联结词集合,若任一个命题公式都可以由s中的联结词表示出来命题公式与之等价,则称S是一个联结词完备集。 也就是说一个连接词集合,能表达出所有真值函数,称为完备集 以下是完备集: S1={¬,∧,∨} —— 否定、合取、析取 S2={¬,∧,∨,→} —— 否定、合取、析取、蕴涵 S3={¬,∧,∨,→,↔} —— 否定、合取、析取、蕴涵、等价 S4={¬,∧} —— 否定、

operator运算符重载笔记运算符重载就是给 C++ 已有的运算符,重新定义它作用于自定义类 / 结构体对象时的行为。
只能重载语言已存在的运算符,不能创造新运算符;
仅作用于类 / 结构体对象,不能修改 int、double 等内置类型的运算规则;
底层本质是函数重载,运算符是一种特殊函数。
:: . .* ?: sizeof 以上 5 个运算符绝对不允许重载。
隐含左操作数为当前对象 this;
语法格式:返回值 operator运算符(右操作数)
class A {
public:
A operator+(const A& b);
};
// 使用:a + b 等价于 a.operator+(b)
限制:左操作数必须是本类对象。
无隐式 this 指针,左右操作数都需要显式传入参数;
适用场景:左操作数不是自定义类(例如 3 + 对象);
核心优势:友元可直接访问类私有、保护成员,无需调用公有接口。
friend A operator+(const A& a, const A& b);
声明方式:类内写 friend class 类名;,声明位置不区分公私。
作用:让另一个类的全部成员函数都能访问当前类私有成员,多个运算符重载时更简洁;
关键特性:
友元单向:B 是 A 的友元 ≠ A 是 B 的友元;
不可传递:C 是 B 友元、B 是 A 友元,C 不能访问 A 私有成员;
不能继承。
class Point {
private:
int x, y;
friend class FriendClass; // 声明友元类
public:
Point(int x=0, int y=0) : x(x), y(y) {}
};
class FriendClass {
public:
Point operator+(const Point& p1, const Point& p2) {
Point res;
res.x = p1.x + p2.x;
res.y = p1.y + p2.y;
return res;
}
};
int main() {
Point a(1,2), b(3,4);
FriendClass fc;
Point c = fc.operator+(a, b);
return 0;
}
说明:日常运算符重载极少使用友元类,全局友元函数更通用。
运算符优先级、结合性、操作数个数无法修改;
单目重载后仍是单目,双目重载后仍是双目;
不要篡改原有语义,+ 代表加法、== 代表相等判断,符合阅读习惯;
以下运算符仅能使用成员函数重载,禁止友元: 赋值 =、下标 []、函数调用 ()、箭头 ->
双目算术:+ - * / % 只读运算,一般返回全新对象,不修改原对象。
赋值运算符 = 只能成员重载,用于深拷贝,解决浅拷贝内存泄漏。
关系运算符:== != > < >= <= 返回 bool,仅做对象成员比较。
单目自增自减 ++ -- 区分前置、后置,后置重载必须加 int 占位参数区分。
流输入输出 >> << 只能全局友元重载,左操作数是 cin/cout,不是自定义类。
下标 []、括号 ()、箭头 -> 仅成员重载,分别用于容器、仿函数、智能指针。
成员重载左操作数必须为本类对象;友元无此限制,可直接访问私有成员;友元单向、无传递性。
++/-- 后置重载必须添加 int 占位形参,仅用于编译器区分,无实际运算作用。
<<、>> 只能用友元函数,不能写成类成员函数。
重载函数形参、成员函数尽量加 const,保证只读不修改数据。
能返回引用 & 就返回引用,减少对象拷贝;纯算术运算除外,需返回临时新对象。
返回值没有统一规定,遵循「贴合原生运算符语义、减少拷贝、支持链式调用」,分类标准写法如下:
+ - * / % → 返回类临时对象只读运算,不修改原对象,不能返回引用(会产生野引用)
class Point {
public:
int x, y;
Point operator+(const Point& other) const {
Point res;
res.x = this->x + other.x;
res.y = this->y + other.y;
return res;
}
};
= += -= *= /= → 返回当前类引用修改自身对象,支持链式赋值 a = b = c,仅成员重载
// 赋值=
Point& operator=(const Point& other) {
if (this == &other) return *this; // 防止自赋值
this->x = other.x;
this->y = other.y;
return *this;
}
// 复合赋值 +=
Point& operator+=(const Point& other) {
this->x += other.x;
this->y += other.y;
return *this;
}
== != < > ! → 返回 bool用于真假判断,函数末尾加 const
bool operator==(const Point& other) const {
return this->x == other.x && this->y == other.y;
}
bool operator<(const Point& other) const {
return this->x < other.x;
}
++ --前置:返回对象引用(先修改,返回自身)
后置:返回新临时对象(先保存原值,再修改),带 int 占位参数
// 前置 ++p
Point& operator++() {
x++; y++;
return *this;
}
// 后置 p++
Point operator++(int) {
Point temp = *this;
x++; y++;
return temp;
}
<< >> → 返回流对象引用(ostream& / istream&)友元重载,支持连续链式输出输入 cout << a << b
friend ostream& operator<<(ostream& os, const Point& p) {
os << "x:" << p.x << ", y:" << p.y;
return os;
}
friend istream& operator>>(istream& is, Point& p) {
is >> p.x >> p.y;
return is;
}
[]:返回成员引用,支持读写 arr[0] = 10
->:多用于智能指针,返回对象指针 / 引用
():仿函数,返回值根据业务自定义
只读运算返新对象,修改自身返引用; 比较判断返回 bool,输入输出返流引用; 自增前置引用、后置临时对象。
运算符重载本质是把运算符当作特殊函数,为自定义类定制运算逻辑;分成员函数、全局友元函数两种主流写法(拓展友元类极少使用),存在固定不可重载运算符与语法限制;多用于实现对象加减、比较、控制台打印、数组下标访问等场景;牢记友元关系单向、不可传递。