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

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

作者: 一般的路人丙 | 来源:发表于2017-02-07 10:41 被阅读0次

    Classes的两个经典分类:

    • Class without pointer member(s)
      complex
    • Class with pointer member(s)
      string

    String class

    String class

    String s3(s1); // s3初值为s1,拷贝
    s3=s2; //拷贝,引发与刚才不一样的函数

    编译器给的默认的可以用,就用
    但是这里不可以用,用的话会传指针,不是真的复制。

    Big Three,三个特殊函数

    Big Three,三个特殊函数

    动态分配,而不是在类里面放一个数组。
    所以是一个指针。

    不能用编译器的,所以要写出来。
    234是比 Complex 新增加的,Complex 里不曾出现
    2.String 接受的是自己这种东西,所以叫拷贝构造
    3.复制的是自己这种东西,拷贝赋值

    所有的类的定义,对 big3都不会加 const,因为必然要修改

    ctor 和 dtor(构造函数和析构函数)

    ctor 和 dtor(构造函数和析构函数)

    2-1
    要想到最后有一个结束符'\0'
    最后一步,清理的函数。
    动态内存,所以要清理。否则会造成溢出。
    class 里有指针,多半要使用动态分配,有动态分配,就要在退出时释放这部分内存。

    class with pointer members 必须有 copy ctor 和 copy op=(赋值assignment operator)

    class with pointer members 必须有 copy ctor 和 copy op=(赋值assignment operator)

    如果使用编译器默认,则在赋值时会拷贝指针,而不是数据。
    看起来像是内容相同,但是 a 和 b 指向了相同的数据,改变 a 同时也会改变 b。

    copy ctor(拷贝构造函数)

    copy ctor(拷贝构造函数)

    2-2
    alias 叠名
    是一件危险的事

    copy assignment operator(拷贝赋值函数)

    copy assignment operator(拷贝赋值函数)

    2-3
    赋值过程:
    先把左边清空,然后建立一个和右边一样的空间,再把右边拷贝到左边。
    首先,检测是不是自我赋值,不只是同名赋值,很可能是指针指向同一个类。如果相同,就直接返回指针。
    然后再拷贝:

    1. 删掉
    2. 建立空间
    3. 拷贝内容


      赋值前
    删掉 建立空间 拷贝内容

    如果不检测自我赋值,会发生什么:

    1. 删掉了唯一值
    2. 无法建立空间,因为检测不出长度,出错
    如果不检测自我赋值

    output 函数

    output 函数

    要写操作符重载
    有什么可以直接丢给 cout呢?有,写在 inline 里面的 get_c_str()

    所谓 stack(栈),所谓 heap(堆)

    所谓 stack(栈),所谓 heap(堆)

    放在栈里的内容,在离开作用域后会自动删除
    放在堆里的内容,需要自己手动删除

    stack objects 的生命期

    stack objects 的生命期

    auto object

    static local objects 的生命周期

    static local objects 的生命周期

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

    globe object 的生命周期

    globe object 的生命周期

    heap objects 的生命周期

    heap objects 的生命周期

    new:先分配 memory,再调用 ctor

    new:先分配 memory,再调用 ctor

    绝大多数的 new 被分解为三个部分:

    1. 调用 operator new,其内部调用 malloc(n),分配内存的函数
    2. 转换类型
    3. 调用构造函数,全名是 Complex::Complex(this,i,j)
    new:先分配 memory,再调用 ctor

    delete:先调用 dtor,再释放 memory

    delete:先调用 dtor,再释放 memory
    1. 执行析构函数~String(ps),删除字符串占用的空间
    2. 释放内存 operator delete(ps),调用free(ps)
    delete:先调用 dtor,再释放 memory

    动态分配所得的内存块(memory block),in VC

    动态分配所得的内存块(memory block),in VC

    VC调试中Complex占用的,复数占用8B,调试占用32+4,cookie,42,共52B,总共占用64B(必须是16的倍数)所以有34B 的填充物
    Release Mode,8B,cookie 占用42,共16B
    cookie 内容00000041,4代表4
    16,1代表已分配
    VC调试中String 占用的,指针占用4B,调试占用32+4,cookie,42,共48B,没有填充物
    Release Mode,4B,cookie 占用4
    2,共12B,总共占用16B,其中4B为填充物。

    动态分配所得的 array

    动态分配所得的 array

    2-1
    Complex* p=new Complex[3];

    array new 一定要搭配 array delete

    array new 一定要搭配 array delete

    不正确的用法少了[],少了[]并不会发生array占用的内存泄漏。
    有[]调用3次析构函数
    没有[]调用1次析构函数,有两个并不回收

    编程实例

    class String
    {
    public:
        String(const char* cstr=0);
        String(const String& str);
        String& operator= (const String& str);
        ~String();
        char* get_c_str() const {return m_data;}
        
    private:
        char* m_data;
    };
    
    inline
    String::String(const char* cstr=0)
    {
        if (cstr){
            m_data = new char[strlen(cstr)+1];
            strcpy(m_data,cstr);
        }
        else{ //未指定初值
            m_data = new char[1];
            *m_data= '\0';
        }
    }
    
    inline
    String::~String()
    {
        delete[] m_data;
    }
    
    inline
    String::String(const String& str)
    {
        m_data = new char[ strlen(str.m_data) + 1];
        strcpy(m_data,str.m_data);
    }
    
    inline
    String& 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;
    }
    

    进一步补充:static

    进一步补充:static

    静态成员函数没有 this pointer,所以不能使用 this pointer 的功能。

    进一步补充:static

    静态的变量要在外面赋初值

    进一步补充:把 ctors 放在 private 区

    进一步补充:把 ctors 放在 private 区

    只用一次的函数。构造函数放在 private 中,

    进一步补充:把 ctors 放在 private 区

    只有第一次调用的时候才会定义,这以后就会存在,并且只会有一份。

    进一步补充:cout

    进一步补充:cout

    进一步补充:class template,类模板

    进一步补充:class template,类模板

    进一步补充:function template,函数模板

    进一步补充:function template,函数模板

    把责任分开,很有必要
    这种东西叫做算法

    进一步补充:namespace

    进一步补充:namespace
    • using directive
    using namespace std;
    
    • using declaration
    using std:cont;
    
    • 用全名

    更多细节与深入

    更多细节与深入
    • operator tyge() const;
    • explicit complex(…):initialization list{}
    • pointer-like object
    • function-like object
    • Namespace
    • template specialization
    • Standard Library
    • variadic template
    • move ctor

    相关文章

      网友评论

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

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