美文网首页
Boolan C++面向对象高级编程(上)第二周

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

作者: MRSUMMER163 | 来源:发表于2017-07-27 16:37 被阅读0次

    第二周

    七、三大函数

    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.拷贝构造函数

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

    5.拷贝赋值函数

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

    八、堆、栈与内存管理

    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。

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

    3.delete

    delete:先调用dtor,再释放memory

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

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

    Release mode,16

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

    5.动态分配所得的数组

    vc用一个整数记录3

    array new 一定要搭配array delete

    九、复习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,只能处理静态数据。

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

    2.把构造函数放在private区

    3.cout

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

    4.class template,类模板

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

    5.function template,函数模板

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

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

    6.namespace

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

    使用标准库中的东西:

    using directive

    using namespace std;

    全部打开

    using declaration

    using std::cout;

    一条一条打开

    直接std::cout

    相关文章

      网友评论

          本文标题:Boolan C++面向对象高级编程(上)第二周

          本文链接:https://www.haomeiwen.com/subject/foozkxtx.html