侯捷C++面向对象编程上day3
侯捷C++面向对象编程(上)课程打卡
侯捷C++面向对象编程(上)课程打卡 Day3
5、操作符重载与临时对象
5.1操作符重载
在C++中,我们可以定义加法等操作符,比如我们可以定义两个是石头的加法
5.1.1成员函数实现
成员函数: complex :: function …… 前面带有class的名称(在class里事先声明了的)
1 | inline complex& complex::operator += (const complex& r) |

所有的成员函数都带有一个隐藏的参数this(是一个指针),this指向调用这个函数的调用者
- 定义函数的时候,在参数列中不能写出来
this,直接用即可 - 函数里可写可不写,但当传入参数与成员变量名相同时要写
1 | public: |
1 | c3 += c2 += c1 //c2加了c1后如果返回void就无法进行c3的操作了 |
将操作符写为void函数也可以,但为了可以兼容c3+=c2+=c1的形式,写成返回引用更好。
5.1.2 非成员函数实现

非成员函数没有this
应对三种使用方法,写出三种方式
非成员函数是global函数——为了后面两种使用方法
这些函数不能返回引用,必须值传递
在函数中创建的新变量 (local 变量),要返回
5.1.3 output函数 << 的重载
cout不认识新定义的这种复数,因此也需要对<<进行操作符重载
只能全局函数,不能成员函数——导致使用时方向相反
1 |
|
ostream& 是 cout 的 classname
参数传递:os 在函数中会变化,所以不能加 const
返回值传递:为了避免 cout << c1 << conj(c1); 连续输出,不用 void
cout << c1 返回值需要与 cout 类型一致
5.2 临时对象

classname () 创建一个classname类型的临时对象——不需要名称,生命只有一行
6、带指针的类:三大函数

析构函数:~String();
拷贝构造函数 copy ctor:String (const String& str);——string s3(s1)
拷贝赋值函数copy op= :String& operator=(const String& str);—–s3=s2
编译器默认的是拷贝构造赋值,编译器默认的方式只是拷贝了指针(浅拷贝),而不是指针指向的数据。

alias(别名)和 memory leak(内存泄漏)都是十分危险的
因此,如果类中有指针,一定自己写这两个函数
6.1ctor和dtor(构造和析构函数)
6.1.1ctor构造函数
这里的new是申请的字符串的空间
1 | inline |
这里的 new 是申请的指针的空间,String()里面还有一个 new
1 | String* p = new String("hello"); |
6.1.2dtor析构函数
1 | inline |
每一个new都对应一个delete—–一定要释放申请的内存
类对象死亡的时候(离开作用域),析构函数会被自动调用
例:这里结束会调用三次 dtor
1 | { |
6.2 copy ctor 拷贝构造函数
1 | inline |
1 | String s1("hello "); |
6.3 copy op= 拷贝赋值函数
- 先杀死调用者
- 重新申请指定大小的空间
- 复制字符串内容到调用者
1 | inline |
一定要在开始就检测自我赋值,因为a=a时第一步 delete 了后,会使第三步出现问题
7、堆、栈,内存管理
7.1堆和栈
Stack 栈,是存在于某一个作用域的一块内存空间。
例如当你调用函数时,函数本身就会产生一个stack用于放置它所接受的参数,以及返回地址;在函数本体内声明的任何变量其所使用的内存块都取自上述的stack
Heap 堆,或者称为system heap,是指由操作系统提供的一块global内存空间,程序可以动态分配从中获得若干区块。
可以用new来动态取得
在 stack 中的是自动生成的空间,作用域结束空间会自动释放
在 heap 中的是自己申请的空间,需要自己释放
1 | { |
7.2对象生命周期
stack objects的生命周期
c1就是所谓stack object,其生命在作用域结束之际结束。这种作用域内的object,又称为auto object,因为它会被自动清理(结束自动调用析构函数)
1
2
3{
complex c1(1,2);
}static local objects 的生命期
若在前面加上
static后,其会存在到整个程序结束1
2
3{
static complex c2(1,2);
}global objects 的生命期
写在任何作用域之外的对象,其生命在整个程序结束之后才结束,你也可以把它视为一种 static object,其作用域是整个程序
1
2
3
4
5
6
7...
complex c3(1,2);
int main()
{
...
}heap objects 的生命期
p所指的便是 heap object,其生命在它被delete之际结束1
2
3
4
5{
complex* p = new complex;
...
delete p;
}
7.3new和delete
7.3.1 new
new: 先分配memory,再调用ctor

- 分配内存:先用一个特殊函数,按 class 的定义分配了两个
double的大小 - 转型(忽视)
- 调用构造函数,赋值
(1,2)
7.3.2 delete
delete:先调用 dtor, 再释放 memory

- 调用析构函数——释放的是
m_date指向的字符串Hello的空间(即构造函数中new申请的空间) - 释放内存:用一个特殊函数释放了
ps指向的空间(即String* ps = new String("Hello");中new申请的空间)
7.4内存动态分配
7.4.1 array new/delete
array new 一定要搭配 array delete
new后有**[ ]—> delete后加[ ]**
普通的delete只调用一次析构函数——剩下两个指针的指向的空间没有调用析构函数,内存泄漏
这种情况发生在有指针的类,但最好都这样写
7.4.2 对象的动态内存分配
对象与简单的数据类型没有什么不同
侯捷C++面向对象编程上day3
1.STL学习打卡Day07
2.STL学习打卡Day06
3.STL学习打卡Day05
4.STL学习打卡Day04
5.STL学习打卡Day03
6.STL学习打卡Day02
7.STL学习打卡Day01
8.侯捷C++面向对象编程下day6




