美文网首页
网易云课堂C++第二周笔记(GeekBand)

网易云课堂C++第二周笔记(GeekBand)

作者: 林小七Raul | 来源:发表于2016-07-20 00:10 被阅读0次

    1.C++三个特殊的函数(Big Three)
    拷贝构造函数,赋值构造函数和析构函数。一般情况下,一个类里面只要有指针,就一定要定义拷贝构造函数和赋值构造函数。系统默认的拷贝构造函数只能对对象进行浅复制,浅复制只是将对象的数据进行拷贝,而没有生成新的内存空间,可以理解为两个对象同时指向同一个内存地址,只是拷贝了指针,这是一种危险的行为,容易造成内存泄漏。而深复制是建立一块新的内存地址,然后将数据拷贝到这个新的内存之中。以拷贝复制为例,进行
    String a = b;的深复制行为

         Sting &String::operator = (const String &str)
          {
                if(this == &str)
                      return *this;
                delete []m_data;
                m_data = new char[strlen(str.m_data)+1];
                strcpy(m_data, str.m_data);
                return *this;
          }
    

    以上就是一个拷贝赋值函数,首先检测是否为自我赋值(a = a),然后清除要赋值对象里面的数据,然后喂对象分配一块内存,最后将数据赋值到这块内存。这里需要注意的是检测自我赋值,检测自我赋值不仅仅可以提高效率,更重要的一点是能够避免程序出错。如果没有这个功能,当进行 a=a是,由于这是同一个对象,指向的是同一块内存,当执行
    delete []m_data时,会将对象内存清除,里面就没有数据,会造成程序运行时出错。

    析构函数可以理解为对对象进行收尾工作,当对象所在的作用域结束之后,酒会调用析构函数,系统会有默认的析构函数,但值得注意的是,当构造函数使用了new时,析构函数一定要使用delete,在程序中,一个new,一定要对应一个delete,不然就会造成内存泄漏。

    2.堆,栈与内存管理
    以前对堆和栈的概念与区别,以及它们要干什么都是混乱的,现在才总算有了一些了解。
    栈(Stack),是存在于某个作用域的一块内存,当你调用相应的函数时,函数体本身就会形成一个栈,来放置需要接收的函数,在函数体内声明的仁和变量,其内存块都是取自于栈,但函数调用结束后,系统会自动释放栈的内存,也就是说栈所占用的内存又系统自动管理,当相应的作用域结束后,系统就会自动清理栈的内存。也可以理解为栈内存放的是auto object,系统自动管理对象。
    堆(Heap),堆是一块全局的内存空间,可以动态分配内存,是用new,在程序的任意地方都可以得到,在这里再次强调,使用new,就一定要用delete来释放内存,不然将会造成内存泄漏。static local object是存放在堆中,此对象在作用域结束后任然存在,之道程序结束。还有就是global object全局对象。
    在这里来简单说一下new和delete的运行机制
    new(Complex pc = new Complex(1, 2)):
    首先根据数据内容创建一块内存,其实就是在内部调用malloc函数,
    void mem = operator new (sizeof(Complex))
    然后就是转型,也就是强制类型转换
    pc = static_cast<Complex
    >(mem)
    最后就是将数据内容传入到内存中。new简单来说,就是先创建内存,然后调用构造函数。
    而delete就恰恰相反,首先调用析构函数,将内存块里面的数据清除,然后再释放内存块。

      需要注意的是,动态分配内存块并不是你的数据需要多少,就会给你分配多少,实际是分配的内存块远多于数据所需的内存,用于回收和调试。
      还要注意的是,使用new和delete来创建和删除数组时的用法,delete []p,不然将无法释放数组的内存。
      还要注意的是,在如果在一个类里面定义了static函数或者数据,那么static数据将与对象脱离,就可以说static数据不受对象限制,当对象被销毁后,static数据还将存在,直到整个程序结束为止。同时,static数据可以直接通过classname来调用,比如
    

    class Account
    {
    public:
    static double m_rate;
    static void set_rate(const double &x)
    {
    m_rate = x;
    }
    };

    int main
    {
    Account::set_rate(5.0);
    Account a;
    a.set_rate(7.0);
    return 0;
    }

    3.单例(Singleton)设计模式
    单例设计模式在编程中是一种简单,但也是我么常用的一种设计模式,我以前习惯将其理解为就是对对象里的数据进行初始化,现在听了老师讲解后才发现自己的理解太狭隘。
    单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,也就是说,外界不能创建对象,单例类只有一个自己,只有一个唯一的接口,比如:
    class A
    {
    public:
    static A &getInstance() { return a;}
    setup() {}
    private:
    A();
    A(const A &rth);
    static A a;
    }
    注意,如果 A &A::getInstance{return a;}创建在外部的话,当没人使用A时,既不存在对象a, 一旦有人使用,那么a就会一直存在,直到整个程序结束。static数据只能用static函数来获取,在上面的class A中,就是用static函数来获取static数据,要注意的是,static函数只能处理static数据,而且static函数没有this 指针。
    在程序中,我们通过A::getInstance()来获得对象a,A::getInstance().setup(),来获得数据。

    3.类模版 和 函数模版
    类模版就是一个类通过绑定不同类型的数据,进行数据处理,比如
    template<typename T>
    complex<double>c1(2.5, 1.5)
    complex<int>c2(2, 6)
    通过绑定不同的数据类型,来处理相应的数据。

    函数模版无需绑定数据类型,它可以对传进来的数据进行实參推导,比如
    const T &min(const T &a, T &b){ return b < a ? a:b;}

    4.虚函数
    虚函数就是最直接的理解就是在函数前面加上virtual关键字的函数,虚函数数的作用在我看来,就是方便子类对父类中函数的修改,方便子类对象和父类对象对同名函数的调用。比如下面的这个例子:
    class A

    public:
    void print(){ cout<<"A...... "<<endl;}

    class B:public A
    {
    public:
    void print(){cout<<"B......"<<endl;}
    }

    5.继承
    继承是体现C++多态性的一个重要特性,它是is-a的关系,我的理解它就是一种包含的关系,也就是说,子类包含类基类的特性,同时在基类的基础上可以添加有别于基类的行为。
    比如下面的UML图

    屏幕快照 2016-07-27 19.45.15.png

    Rectangle类继承了Shape类,那么Retangle继承了Shape类的行为,注意Shape类里面有两个纯虚函数,只要类里面有纯虚函数,那么这个类就是抽象类,抽象类不能定义对象,而且继承了抽象类的子类必须要复写基类里面的纯虚函数,不然子类也会是抽象类。
    这里要注意一个,基类里面的非虚函数就是不希望子类复写的函数,而虚函数就是基类希望子类去复写的函数。非虚函数也可以复写,但在父类和子类对象的使用过程中会带来不便,所以建议不要复写基类的非虚函数,如果一定要复写基类里面的函数,就将此函数定义为虚函数。

    6.Composition
    Composition模式我就把他理解为就是一个组合模式,老师说这是一种has-a 的关系,也就是包含关系,其实上面的UML中Retangle类就包含类一个Point类,完整的UML应该如下:


    屏幕快照 2016-07-27 20.24.26.png

    (由于用的软件问题,组合关系就用黑色箭头代替一下)

    7.delagetion(委托设计模式)
    委托设计模式就是通过一个中介来实现自己要完成的事。比如你现在租房,你会到58,赶集等网站去寻找房源,然后通过这个中介来同房东交流,当然你也可以直接找房东,但会浪费你的时间,结构图如下


    屏幕快照 2016-07-27 20.39.59.png

    房客通过中介来找房,中介可以同时处理多个房客的需要,这就大量节省了房客的时间,但中介也要收取一定的费用,在委托模式中也一样,消耗一定的性能,但能大大提高程序的效率。

    相关文章

      网友评论

          本文标题:网易云课堂C++第二周笔记(GeekBand)

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