C++ 开发工程师 第二周笔记 boolan.com
2017-02-09 22:54
267 查看
第二周
string类的设计
构造函数和析构函数
拷贝构造函数
拷贝赋值函数
检测自我赋值
output函数
stack 栈 heap 堆
生命周期
new
delete
动态分配得的内存块 VC
动态分配得的array VC
复习string类的实现
static
构造函数放在private
类模版 class template
函数模版 function template
namespace
其他
防卫式声明
构造函数
拷贝构造 参数是自己的类型
= 拷贝赋值
如果不写,编译器会完全复制过去,对于带指针的类,不好!
参数也是自己类型
数据不应该放到数组,最好是用多少 放多少
析构函数
带指针的类一定要有big three 拷贝构造函数 拷贝赋值函数 析构函数
c的字符串是一个指针指向字符串头,最后加一个结束符号
如果初始化一个空字符串,则长度为1,放进去结束符号。
如果初始化一个非空字符串,则长度为字符串长度
清理,析构函数要将动态分配的内存释放掉。
如果没有,浅拷贝会造成
上图蓝色的两行等同。
两个对象都已经存在
1. 清空被赋值的对象
2. 重新分配一个和值一样大的空间
3. 拷贝
大气,效率高,否则可能造成数据丢失 甚至崩溃。
Stack 是存在与某作用域(scope)的一块内存空间(memory space)。比如,当你调用函数,函数本身会形成一个stack来放置它所接收的参数,以及返回地址。
在函数本体(function body)内声明的任何变量,其所使用的内存块都取自上述stack。
Heap 又称 system heap,是由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区块(blocks)。
编译器进行如下操作
1. 分配内存
2. 将得到的void指针转型
3. 通过指针调用构造函数 构造函数是成员函数,有this
编译器转化为两个动作
1. 调用析构函数
2. operator delete 释放内存 内部调用
图中一个格4字节
灰色部分是调试模式下额外的分配的内存,红色部分是cookie,上下各一个
上下cookie记录分配的长度,比如,64,十六进制为40,最后一个bit代表该块内存是否已分配,故41。因为分配的内存为16的倍数,故可以使用最后一位表示。
VC下 分配的内存一定为16的倍数,pad为填补
其他编译器类似。
分配数组,vc用一个整数记录个数
array new 要搭配 array delete
delete 根据cookie删除内存,无论是
养成好习惯,array new 搭配 array delete。
class 头
怎么放数据
数组 大小固定不好
指针 动态分配内存 32位 指针4字节
数据 private
准备哪些函数
构造函数
无return type
设计参数 接受一个c字符串
参数不改变 加const
有默认值 可以不给初值
在声明外写函数体 String::String(…)
参数有东西吗
有 计算大小 注意字符串结尾 拷贝数据
没有 空字符串也有结束符
inline
big three
拷贝构造函数
是构造函数 名字 没有返回类型
参数是自己类型的
传reference
不改变 const
分配空间
拷贝数据
inline
拷贝赋值函数
函数名 operator=
参数是自己类型
传引用
不改变参数 参数类型const
返回值
结果是自己类型的
by reference?
返回值是不是local object
不是 传reference
旧数据删掉
分配空间
拷贝数据
返回值 便于连续赋值
是否自我赋值
判断来源和目的是不是相同
析构函数
释放所有资源 文件 窗口 内存 等
array new 对应 array delete
inline
其他辅助函数
取字符函数 get_c_str()
函数是否改变数据 const
之前,成员变量有好几份,成员函数只有一份,实际上,成员函数有this指针,来作用于不同对象。
带有static的变量和对象脱离了,只有一份。带有static的函数也是只有一份。
静态函数没有this pointer,因此不能像普通参数一样访问对象的非静态变量,只能存取静态数据。
语法上,需要在类的外面写黄色一行,可以赋值,也可以不赋值,严格讲,这一行叫定义,该行会使变量获得内存。类中的
调用静态函数有两种方式:
1. 通过对象object调用
2. 通过类名class name 调用
单例模式,
不完美,如果根本没有调用这个类,那么这个
改进
把
不指定数据类型,用
这里用
函数模版不用指出数据类型,编译器会自动进行推倒 argument deduction
重载
标准库中算法使用函数模版。
为了避免冲突,使用
把自己的东西包在std命名空间中,可以分段写。
使用有两种方法
1. 使用命令 directive
2. 使用声明 declaration
string类的设计
构造函数和析构函数
拷贝构造函数
拷贝赋值函数
检测自我赋值
output函数
stack 栈 heap 堆
生命周期
new
delete
动态分配得的内存块 VC
动态分配得的array VC
复习string类的实现
static
构造函数放在private
类模版 class template
函数模版 function template
namespace
其他
第二周
string类的设计
防卫式声明
构造函数
拷贝构造 参数是自己的类型
= 拷贝赋值
如果不写,编译器会完全复制过去,对于带指针的类,不好!
参数也是自己类型
数据不应该放到数组,最好是用多少 放多少
析构函数
带指针的类一定要有big three 拷贝构造函数 拷贝赋值函数 析构函数
构造函数和析构函数
c的字符串是一个指针指向字符串头,最后加一个结束符号
\0。
如果初始化一个空字符串,则长度为1,放进去结束符号。
如果初始化一个非空字符串,则长度为字符串长度
strlen+1,不要忘记结束符号。
清理,析构函数要将动态分配的内存释放掉。
拷贝构造函数
如果没有,浅拷贝会造成
World\0区域没有指针引用,造成内存泄漏,
Hello\0被引用两次,修改一个,另一个也同时修改。
上图蓝色的两行等同。
拷贝赋值函数
两个对象都已经存在
1. 清空被赋值的对象
2. 重新分配一个和值一样大的空间
3. 拷贝
检测自我赋值
大气,效率高,否则可能造成数据丢失 甚至崩溃。
output函数
cout可以接受字符串指针。
stack 栈 heap 堆
Stack 是存在与某作用域(scope)的一块内存空间(memory space)。比如,当你调用函数,函数本身会形成一个stack来放置它所接收的参数,以及返回地址。
在函数本体(function body)内声明的任何变量,其所使用的内存块都取自上述stack。
Heap 又称 system heap,是由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区块(blocks)。
生命周期
new
编译器进行如下操作
1. 分配内存
operator new函数 内部调用
malloc
2. 将得到的void指针转型
3. 通过指针调用构造函数 构造函数是成员函数,有this
delete
编译器转化为两个动作
1. 调用析构函数
2. operator delete 释放内存 内部调用
free
动态分配得的内存块 VC
图中一个格4字节
灰色部分是调试模式下额外的分配的内存,红色部分是cookie,上下各一个
上下cookie记录分配的长度,比如,64,十六进制为40,最后一个bit代表该块内存是否已分配,故41。因为分配的内存为16的倍数,故可以使用最后一位表示。
VC下 分配的内存一定为16的倍数,pad为填补
其他编译器类似。
动态分配得的array VC
分配数组,vc用一个整数记录个数
array new 要搭配 array delete
delete 根据cookie删除内存,无论是
delete还是
delete[]都会完整的删除动态分配的内存,此处不会发生内存泄漏。
delete[]会调用多次析构函数,用
delete可能会导致字符串所指的地址的内存泄漏。
养成好习惯,array new 搭配 array delete。
复习string类的实现
防卫式声明class 头
怎么放数据
数组 大小固定不好
指针 动态分配内存 32位 指针4字节
数据 private
准备哪些函数
构造函数
无return type
设计参数 接受一个c字符串
参数不改变 加const
有默认值 可以不给初值
在声明外写函数体 String::String(…)
参数有东西吗
有 计算大小 注意字符串结尾 拷贝数据
没有 空字符串也有结束符
inline
big three
拷贝构造函数
是构造函数 名字 没有返回类型
参数是自己类型的
传reference
不改变 const
分配空间
拷贝数据
inline
拷贝赋值函数
函数名 operator=
参数是自己类型
传引用
不改变参数 参数类型const
返回值
结果是自己类型的
by reference?
返回值是不是local object
不是 传reference
旧数据删掉
分配空间
拷贝数据
返回值 便于连续赋值
是否自我赋值
判断来源和目的是不是相同
析构函数
释放所有资源 文件 窗口 内存 等
array new 对应 array delete
inline
其他辅助函数
取字符函数 get_c_str()
函数是否改变数据 const
static
之前,成员变量有好几份,成员函数只有一份,实际上,成员函数有this指针,来作用于不同对象。
带有static的变量和对象脱离了,只有一份。带有static的函数也是只有一份。
静态函数没有this pointer,因此不能像普通参数一样访问对象的非静态变量,只能存取静态数据。
语法上,需要在类的外面写黄色一行,可以赋值,也可以不赋值,严格讲,这一行叫定义,该行会使变量获得内存。类中的
static double m_rate只是声明,这个变量实际上是脱离类的。
调用静态函数有两种方式:
1. 通过对象object调用
2. 通过类名class name 调用
构造函数放在private
单例模式,
a只有一个,外部通过
getInstance得到自己,该函数返回
a,再通过这个
a调用其他模式。
不完美,如果根本没有调用这个类,那么这个
a一直存在,浪费。
改进
把
a放到函数里,如果不调用这个函数,
a就不存在。
类模版 class template
不指定数据类型,用
T代替,
template<typename T>。
函数模版 function template
这里用
template <class T>和上面的
typename T相通。
函数模版不用指出数据类型,编译器会自动进行推倒 argument deduction
重载
<运算符,完成大小比较。
标准库中算法使用函数模版。
namespace
为了避免冲突,使用
namespace std { ... }
把自己的东西包在std命名空间中,可以分段写。
使用有两种方法
1. 使用命令 directive
using namespace std;将这个命名空间全部打开
2. 使用声明 declaration
using std::cout;
其他
相关文章推荐
- C++ 开发工程师 第三周笔记 boolan.com
- Boolan-C++开发工程师-C++面对对象高级编程(上)- 第二周笔记
- C++ 开发工程师 第一周笔记 boolan.com
- Boolan-C++开发工程师-泛型编程-第一周笔记
- Boolan——C++开发工程师——C++面对对象高级编程(上)—— 第一周笔记
- Boolan-C++开发工程师-C++面对对象高级编程(上)- 第三周笔记
- Boolan c++面向对象下 第二周笔记
- Boolan博览网C++开发课程第二周笔记
- C++面向对象第二周笔记<Boolan>
- C++开发工程师课程第一周笔记 GeekBank
- Boolan C++面向对象高级编程(上)第二周笔记
- C/C++面试软件开发工程师遇到的一道关于循环的笔记题
- [Boolan-C++学习笔记]第二周整理
- [Boolan] C++第二周学习笔记
- ATL开发指南学习笔记: COM与C++的VTable(虚拟表)
- Boolan c++学习第二周笔记
- 一个软件开发工程师的零散笔记总汇(一)
- COM组件开发实践(四)---From C++ to COM :Part 1
- COM组件开发实践(六)---From C++ to COM :Part 3
- 一个软件开发工程师的零散笔记总汇(三)