美文网首页
勿在浮沙筑高台--P7-P9

勿在浮沙筑高台--P7-P9

作者: Catherin_gao | 来源:发表于2021-01-29 19:59 被阅读0次

    总:Classes的两个经典分类

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

    一. string class

    #ifndef  __MYSTRING__             string.h
    #define __MYSTRING__
    
    class String
    {
    ...
    };
    
    String::function(...) ...
    Global::function(...) ...
    
    #endif
    
    int main(){
      String s1();
      String s2("hello");
    
      String s3(s1);
      cout << s3 << endl;
      s3 = s2;
      cout << s3 <<endl;
    }
    

    二. Big Three, 三个特殊函数

    • 一般创建一个字符指针,指向字符串。因为字符串的大小不确定。
    • Big Three:拷贝构造、拷贝赋值、析构函数。
    • 拷贝构造:输入参数为string类型。
    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;
    }
    

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

    • new动态分配内存,所以需要在析构函数中 delete。
    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;
    }
    
    {
       String s1();
       String s2("hello");
    
       String* p = new String("hello");
       delete p;
    }
    

    四. 必须有拷贝构造和拷贝赋值函数

    • 浅拷贝:别名
    • 深拷贝

    五. 拷贝构造函数

    inline 
    String:String(const String& str){
        m_data = new char[ strlen(str.m_data) +1 ]
        strcpy(m_data, str.m_data)
    }
    
    {
        String s1("hello");
        String s2(s1);
     // String s2 = s1;
    }
    

    六. 拷贝赋值函数

    • 把一个对象s1拷贝给另外一个对象s2。
    • (1)先把s2清空,(2)再构造一块和s1相同大小的空间,(3)再拷贝回去。
    inline
    String& String::opeator=(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;
    }
    

    七. output函数

    #include<iostream.h>
    ostream operator<<(ostream& os, const String& str){
        os<< str.get_c_str();
        return os;
    }
    
    {
        String s1("hello");
        cout << s1;
    }
    

    八. stack 栈,heap堆

    • Stack,存在于某作用域(scope)的一块内存空间。例如当你调用函数,函数本身会形成一个stack用来放置所接收的参数,以及返回地址。
    • 在函数本体内声明的任何变量,其所使用的的内存块都取自stack。
    • Heap, 或 system heap,指有操作系统提供的一块global内存空间,程序可以动态分配若干区块。
    class Complex{...};
    ...
    {
        Complex c1(1, 2);
        Complex* p = new Complex(3);
    }
    

    九. objects的生命期

    class Complex{...};
    ...
    {
       Complex c1(1, 2);
    }
    
    • c1是stack object,其生命在作用域scope结束结束。这种作用域内的object,成为 auto object,因为会被自动清理。
    class Complex{...};
    ...
    {
       static Complex c2(1, 2);
    }
    
    • c2是static object, 其声明在作用域(scope)结束之后仍然存在,直到整个程序结束。
    class Complex {...};
    ...
    Complex c3(1, 2);
    
    int main(){
     ...
    }
    
    • c3是global object, 其声明在整个程序结束后才结束,也可以视为一种static object, 其作用域是整个程序。
    class Complex {...};
    ...
    {
        Complex* p = new Complex;
        ....
        delete p;
    }
    
    • p是heap object,其声明在deleted之后结束。
    class Complex {...};
    ...
    {
        Complex* p = new Complex;
    }
    
    • 会出现内存泄露, p所指的heap object 仍然存在,但指针p的声明已经结束了,作用域之外也看不到p,没办法释放内存。

    十. new: 先分配memory,再调用构造函数

    Complex *pc;
    
    void* mem = operator new( sizeof(Complex) ); //分配内存
    pc = static_cast<Complex*>(mem);                   //转型
    pc->Complex::Complex(1, 2);                             //构造函数
    // Complex::Complex(pc, 1, 2); 
    

    十一. 先调用析构函数,再释放memory

    delete ps;
    
    String::~String(ps);      //析构函数
    operator delete(ps);     //释放内存, 内部调用free(ps)
    

    相关文章

      网友评论

          本文标题:勿在浮沙筑高台--P7-P9

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