《C++程序设计》笔记p6
C++ 手册官方网址
https://en.cppreference.com/
其他运算符的重载
- 算术 运算符重载(+、-、*、/ 、%)
- 比较运算符的重载(>、<、>=、<=、==、!=)
- 位运算符重载(<<、>>、&、|、^、~)
- 赋值运算符重载(=、+=、-=、...)
- 一元运算符的重载(+、-、~)
- 自增、自减运算符重载(++、--(前置)/(后置))
- 索引运算符重载
- 函数调用运算重载
自增、自减运算符重载
前置语法:
class 类名{返回类型 operator++(void) {}返回类型 operator--(void) {}
}
后置语法:
class 类名{返回类型 operator++(int) {}返回类型 operator--(int) {}
}
函数对象
函数对象是指重载了 ()
运算符的对象,此类对象能像函数一样调用,因此叫函数对象。
示例
#include <iostream>
#include <stdlib.h>
#include <string.h>using namespace std;
// class string {
// public:
// string (const char * s){}
// }// 翻译类
class Translater {public:Translater(const char * s) : data(s){}void operator()(const char *who,const char *c) {cout << who << data << c << endl;}private:string data;
};int main(int argc, char * argv[]) {Translater chinese("说:");Translater english("say:");chinese("张三", "你好");english("lisa", "bye");return 0;
}
运算符重载的两种方式
- 成员函数方式
- 全局函数(友元函数)方式
不能作为全局函数重载的运算符。
[]
数组下标运算符()
函数调用运算符->
指针访问成员运算符。=
赋值运算符
运算符重载示例
#include <iostream>
#include <stdlib.h>
#include <string.h>using namespace std;class Complex {public:Complex(int r=0, int i=0):real(r),image(i){}void info(){cout << real << "+" << image << "i\n";}// + 运算符重载Complex operator +(const Complex & right) const {return Complex (this->real +right.real, this->image + right.image);}// == 运算符重载bool operator==(const Complex & right) const {return (this->real == right.real &&this->image == right.image);}// != 运算符重载bool operator!=(const Complex & right) {return !(*this == right);}// += 运算符重载Complex & operator+=(const Complex & right) {this->real += right.real;this->image += right.image;return *this;}Complex operator-(void) {// 返回临时对象(也叫右值对象);return Complex(-this->real, -this->image);}// 前置++运算符重载 Complex & operator++() {cout << "前置++" << endl;this->real += 1;return *this;}// 后置++运算符重载 Complex operator++(int) {cout << "后置++" << endl;Complex r(this->real, this->image);this->real +=1;return r;}/*// 重载[] 运算符int & operator[](int i) {if (i == 0) {return this->real;} else if (i == 1) {return this->image;}i = 0;return i;// throw RangeError(i);}*/private:int real;int image;friend Complex operator+(int left, const Complex &right);friend std::ostream & operator << (std::ostream &o, const Complex c);
};Complex operator+(int left, const Complex &right) {return Complex(right.real + left, right.image);
}
std::ostream & operator << (std::ostream &o, const Complex c) {o << c.real;o << "+";o << c.image;o << "i";return o;
}int main(int argc, char * argv[]) {Complex c1(1, 2);Complex c2(3, 4);Complex c3;// c3 = c1 + 100;c3 = 100 + c1;// 1. // c3 = 100.operator+(c1);// 2.// c3 = operator+(100, c1);// c3.info();cout << c1 << endl; // 1 + 2i//// cout << c3;// cout << endl;// cout << c1[0] << endl; // 1
// cout << c1[1] << endl; // 2
// c1[1] = 5; // 合法 c1: 1+5i;
// c1.info();// c3 = c1 + c2;// c3 = c1.add(c2);// c3.info();// cout << "c1 == c2: "<< (c1 == c2) << endl;// cout << "c1 != c2: "<< (c1 != c2) << endl;// c3 = c1 += c2;// c3 = -c1;// c3 = ++c1;// c1.info();// c3.info();// c3 = c1++;// c1.info();// c3.info();return 0;
}
new
和 delete
运算符重载
作用:自定义对象的存放地址。
new、delete 运算符重载函数
// 动态分配单个对象
void *operator new(size_t sz) {
}
// 释放单个对象
void operator delete(void *ptr,size_t sz) {
}
// 动态分配对象数组
void *operator new[](size_t sz) {
}// 释放对象数组
void operator delete[](void *ptr, size_t sz) {
}
示例
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>using namespace std;// 用于存放Complex 对象的缓冲区
static char mem_buf[4096];
static char * cur_ptr = mem_buf; // 空余空间的开始地址class Complex {public:Complex(int r=0, int i=0):real(r),image(i){}private:int real;int image;friend std::ostream & operator << (std::ostream &o, const Complex c);
};std::ostream & operator << (std::ostream &o, const Complex c) {o << c.real;o << "+";o << c.image;o << "i";return o;
}void * operator new(size_t sz) {cout << "operator new 被调用, sz:" << sz << endl;void * ret = cur_ptr;cur_ptr += sz;return ret;
}
void operator delete(void *ptr,size_t sz) {cout << "operator delete: ptr:" << ptr << "sz:" << sz << endl;
}int main(int argc, char * argv[]) {Complex *p1;Complex *p2;p1 = new Complex(1, 2);cout << *p1 << endl;p2 = new Complex(3, 4);cout << *p2 << endl;cout << *p1 << endl;printf("mem_buf:%p\n", mem_buf);printf("cur_ptr:%p\n", cur_ptr);printf("p1:%p\n", p1);printf("p2:%p\n", p2);delete p2;// delete p1;return 0;
}
异常
异常是 C++ 提供的一种处理程序运行时错误的机制,它运行程序时检测错误,并快速返回到上层调用的地方进行错误处理,同时会调用栈上创建对象的析构函数。
词语:
- 正常
- 错误(Error)
- 异常(Exception)
fa() ---> fb() ---> fc() ---> fd()<--- <--- <---
异常相关的关键字
try catch throw
throw 语句
作用:抛出错误,让程序进入异常状态(走异常路径),返回到上层调用处理待处理。
语法:
throw 错误对象;
try-catch 语句
作用:用于尝试并捕获异常,将程序转成正常状态。
try {可能触发错误的语句。
}
catch (错误类型1 错误对象1) {// catch 子句可以有多个。 处理代码(可以为空)。
}
catch (错误类型2 错误对象2) {处理代码(可以为空)。
}
catch (...) { // catch... 子句只能有一个且只能放在最后。
}
说明:
- try { } 中用于执行可能出现异常的语句。
catch (类型 对象)
根据错误类型依次匹配,如果成功,则被异常被触处理,程序恢复正常状态。catch(...)
用于捕获任何类型的异常,catch (类型 对象)
子句可以有0个、一个或多个。catch(...)
子句可以有0个或一个且只能放在最后。