Boolan C++面向对象高级编程(上)第二周

第二周

七、三大函数

1.三大函数

Class without pointer member-complex

Class with pointer member-string

拷贝构造 String s3(s1)

拷贝赋值 s3=s2

如果没有写拷贝构造和拷贝赋值,编译器会给一套,一个位一个位复制。如果编译器给的够用,不用写,比如前面的complex。带指针的类不能用编译器给的默认版本,要自己写。

除了构造函数,还有三大函数:

(1)拷贝构造

(2)拷贝赋值

(3)析构函数(清理动态分配的内存)

2.析构函数

{

String s1()

String s2(“hello”)

String * p = new String(“hello”)

delete p

}

离开作用域自动析构,p为什么手动析构。

3.Class with pointer members必须有copy ctor和copy op=

使用默认拷贝构造或拷贝赋值(浅拷贝)

(1)内存泄漏

(2)两个对象指向同一块内存(alias)

4.拷贝构造函数

深拷贝,要分配足够的空间,把内容拷贝进去。编译器给的默认版本只拷贝指针,浅拷贝。

Boolan C++面向对象高级编程(上)第二周_第1张图片

5.拷贝赋值函数

先把左边内容清空,分配一个和右边一样大的空间,把右边的内容复制进去。

Boolan C++面向对象高级编程(上)第二周_第2张图片

八、堆、栈与内存管理

1.stack和heap

Stack 是存在于某作用域的一块内存空间。当调用函数,函数本身即会形成一块stack来放置它所接收的参数,以及返回地址。在函数本体内声明的任何变量,其所使用的内存块都取自上述stack。

Heap 是指由操作系统提供的一块global内存空间,程序可动态分配从中获得若干区块。

{

    Complex c1(1,2);

}

Stack object,其生命在作用域结束之际结束。这种作用域内的object,称为auto object,因为它会被自动清理,自动调用析构函数。

{

    Static Complex c2(1,2);

}

Static object,其生命在作用域结束之后仍然存在,直到整个程序结束。

Complex c1(1,2);

int main()

{

}

Global object,其生命在真个程序结束之后才结束。也可以把它视为一种static object,其作用域是整个程序。

Heap object,其生命在它被delete之际结束。如果没有delete,会出现内存泄漏。因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也卡不到p,也就没有机会delete p。

补充:C++内存管理

本期专题将从内存管理、内存泄漏、内存回收这三个方面来探讨C++内存管理问题。

http://blog.csdn.net/zhanghefu/article/details/5003407

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

2.new

new,先分配memory,再调用ctor。

Boolan C++面向对象高级编程(上)第二周_第3张图片

第3步怎么调用构造函数?

3.delete

delete:先调用dtor,再释放memory

Boolan C++面向对象高级编程(上)第二周_第4张图片

4.动态分配所得的内存块,in VC

Boolan C++面向对象高级编程(上)第二周_第5张图片

调试模式,vc分配的内存块是16的倍数,52->64

Release mode,16

上下cookie记录整块给的大小,41(应该是40,最后一个bit表示给出去还是收回来

5.动态分配所得的数组

Boolan C++面向对象高级编程(上)第二周_第6张图片

vc用一个整数记录3

array new 一定要搭配array delete

Boolan C++面向对象高级编程(上)第二周_第7张图片

九、复习String类的实现

1.构造函数、拷贝构造和拷贝赋值不能用const成员函数,因为都要赋值,改变了成员数据。

2.拷贝赋值返回值,因为从c习惯延续的连续赋值,所以返回值不能是void,必须是String&。

3.拷贝赋值要判断是不是自我赋值,if(this=&str) return *this。

4.引用(&出现在type name后面)和取地址(&出现在object前面)

十、扩展补充:类模板、函数模板和其他

1.static

this pointer

成员函数只有一份,成员函数都有一个隐藏的参数this pointer,通过this pointer找到它要处理的对象。

static data members

static member functions

静态成员函数没有this pointer,只能处理静态数据。

Boolan C++面向对象高级编程(上)第二周_第8张图片

注意静态成员数据的定义(初始化)。

2.把构造函数放在private区

Boolan C++面向对象高级编程(上)第二周_第9张图片
Boolan C++面向对象高级编程(上)第二周_第10张图片

3.cout

为什么cout能够接受各种类型的对象,操作符<<重载?

4.class template,类模板

Boolan C++面向对象高级编程(上)第二周_第11张图片

编译器会把T全部替换为double,得到一份代码;把T全部替换为int,得到一份代码。使用模板会使代码膨胀(不是缺点)。

5.function template,函数模板

Boolan C++面向对象高级编程(上)第二周_第12张图片

类模板要明确指出type要绑定为什么,函数模板不用明确指出,因为编译器会做实参推导。

C++标准库中的算法都是函数模板。

6.namespace

标准库中所有都包含在std中。

使用标准库中的东西:

using directive

using namespace std;

全部打开

using declaration

using std::cout;

一条一条打开

直接std::cout

你可能感兴趣的:(Boolan C++面向对象高级编程(上)第二周)