美文网首页
C++面向对象高级编程(上)2019-08-07

C++面向对象高级编程(上)2019-08-07

作者: harrytc | 来源:发表于2019-08-07 23:15 被阅读0次
    拷贝构造和拷贝赋值函数一直傻傻分不清楚现在做一个区分:
    拷贝构造实则是对象一开始并未存在
    但是赋值是赋值给一个已经存在的变量
    
    int main()
    {
    String s1(),
    String s2("hello");
    String s3(s1);      //拷贝构造 以s1为蓝本创建出s3对象,对象并未存在所以就调用拷贝构造函数
    cout << s3 << endl;
    s3 = s2;               //拷贝赋值
    cout << s3 << endl;
    }
    
    类里面只要有指针就要自己写拷贝复制和拷贝赋值,应为指针也是写一份
    
    拷贝赋值
    
    class String
    {
    public:
    String(const char* cstr = 0);
    String(const String& str);  //接受的对象为自己的类型String s3(s1); 
    String& operator=(const String& str);  //操作符重载,接受的也是自己这种东西,拷贝赋值
    ~String();
    char* get_c_str() const { return m_data; } //这里没有改变data所以要加上const
    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;
    }
    
    

    谈一下浅拷贝的问题,若是两个字符串指针a,b现在要将b中的内容复制到a中,浅拷贝只是a,b指针指向同一个区域,而且b中原来的数据也并没有指针指向发生内存泄漏

    拷贝赋值函数

    inline
    String& String::operator=(const String& str)
    {
    //检测是否是自我赋值 
    if (this == &str)
    return *this;
    //若没有这个下面delete之后就没有空间,会出错
    
    delete[] m_data;  //①干掉原来
    m_data = new char[ strlen(str.m_data) + 1 ]; //②创建一个足够的空间
    strcpy(m_data, str.m_data); //③把东西拷贝过来
    return *this;
    }
    
    

    Stack,是存在於某作用域(scope) 的一塊內存空間
    (memory space)。例如當你調用函數,函數本身即
    會形成一個stack 用來放置它所接收的參數,以及返
    回地址。
    在函數本體(function body) 內聲明的任何變量,
    其所使用的內存塊都取自上述stack。

    Heap,或謂system heap,是指由操作系統提供的
    一塊global 內存空間,程序可動態分配(dynamic
    allocated) 從某中獲得若干區塊(blocks)。

    class Complex { … };
    ...
    {
    Complex c1(1,2);
    Complex* p = new Complex(3);
    }
    
    

    c1 所佔用的空間來自stack

    Complex(3) 是個臨時對象,其所
    佔用的空間乃是以new 自heap 動
    態分配而得,並由p 指向。

    stack objects 的生命期

    class Complex { ... };
    ...
    {
    Complex c1(1,2);
    }
    
    

    c1 便是所謂stack object,其生命在作用域(scope) 結束之際結束。
    這種作用域內的object,又稱為auto object,因為它會被「自動」清理。

    static local objects 的生命期
    
    class Complex { … };
    ...
    {
    static Complex c2(1,2);
    }
    
    

    c2 便是所謂static object,其生命在作用域(scope)
    結束之後仍然存在,直到整個程序結束。

    global objects 的生命期
    
    class Complex { … };
    ...
    Complex c3(1,2);
    int main()
    {
    ...
    }
    

    c3 便是所謂global object,其生命在整個程序結束之後
    才結束。你也可以把它視為一種static object,其作用域
    是「整個程序」。

    heap objects 的生命期
    
    class Complex { … };
    ...
    {
    Complex* p = new Complex;
    ...
    delete p;
    }
    

    P 所指的便是heap object,其生命
    在它被deleted 之際結束。

    class Complex { … };
    ...
    {
    Complex* p = new Complex;
    
    }
    
    

    以上出現內存洩漏(memory leak),
    因為當作用域結束,p 所指的heap
    object 仍然存在,但指針p 的生命卻
    結束了,作用域之外再也看不到p
    (也就沒機會delete p)

    new:先分配memory, 再調用ctor
    Complex * pc = = new Complex(1,2 lex(1,2 );
    編譯器轉化為
    void* mem = operator new( sizeof(Complex) ); //分配內存malloc
    pc = static_cast<Complex*>(mem); //轉型
    pc->Complex::Complex(1,2); //構造函數

    delete:先調用dtor, 再釋放memory

    Complex* pc = new Complex(1,2);
    ...
    delete pc;
    Complex::~Complex(pc); // 析構函數 释放指针指向内容
    operator delete(pc); // 釋放內存 释放指针本身 free

    array new 一定要搭配array delete

    String* p = new String[3];
    ...
    delete[] p; //喚起3次dtor
    
    String* p = new String[3];
    ...
    delete p; //喚起1次dto
    

    相关文章

      网友评论

          本文标题:C++面向对象高级编程(上)2019-08-07

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