码迷,mamicode.com
首页 > 编程语言 > 详细

极客班GeekBand - C++面向对象高级开发 - 2

时间:2015-07-28 18:46:55      阅读:310      评论:0      收藏:0      [点我收藏+]

标签:

极客班GeekBand - C++面向对象高级开发 - 2

讲师 - 侯捷

复习Complex类的实现过程

Complex.h

#ifndef __COMPLEX__
#define __COMPLEX__
#include <iostream>
using namespace std;
class complex {
private:
    double re, im;
public:
    complex(double r = 0, double i = 0) :re(r), im(i) {

    }
    complex& operator += (const complex&);
    double real() const {
        return re;
    }
    double imag() const {
        return im;
    }

    friend complex& __doapl(complex*, const complex&);
};
inline complex& complex::operator+= (const complex& r) {
    return __doapl(this, r);
}
inline complex& __doapl(complex* ths, const complex& r) {
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}
inline complex operator +(const complex& x, const complex& y) {
    return complex(x.real() + y.real(), x.imag() + y.imag());
}
inline complex operator +(const complex& x, double y) {
    return complex(x.real() + y, x.imag() + y);
}
inline complex operator +(double x, complex& y) {
    return complex(x + y.real(), y.imag());
}
ostream& operator <<(ostream& os, const complex& x) {
    os << "(" << x.real() << "," << x.imag() << ")";
    return os;
}
#endif

Complex-test.cpp

#include "Complex.h"
int main() {
    complex c1(3, 6);
    c1 += 5;
    cout << c1 << endl;
    complex c2;
    c2 = 5 + c1;
    cout << c2 << endl;
    cout << c1 << c2 << endl;
    return 0;
}

三大函数:拷贝构造,拷贝复制,析构

String.h

#include "String.h"
int main() {
    String s1;
    String s2("hello");
    String s3(s1);  //拷贝构造函数
    cout << s3 << endl;
    s3 = s2;    //拷贝赋值函数
    cout << s3 << endl;
    return 0;
}

String-test.h

#ifndef __MYSTRING__
#define __MYSTRING__
#include <iostream>
using namespace std;
#include <string.h>
class String{
public:
    String(const char* cstr);
    //class with a pointer members
    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(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;
}
inline String::~String() {
    delete[] m_data;
}
ostream& operator<<(ostream& os, const String& str) {
    os << str.get_c_str();
    return os;
}
#endif

栈、堆与内存管理

Stack VS. Heap

Stack,是存在于某作用域(scope)的一块内存空间(memory space)。例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,以及返回地址。
在函数本体(Function Body)内声明的任何变量,其所使用的内存块都取自上诉stack。
Heap,或称为system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从某中获得若干区块(blocks)。

class Complex {

};

{
    Complex c1(1, 2);   //c1所占用的空间来自stack
    Complex* p = new Complex(3);    //Complex(3)是个临时变量,所占用的空间是以new动态分配而得,并由p指向。占用空间来自heap。
}

stack objects、static local objects、global objects的生命期

class Complex {

};
Complex c3(1, 2);

{
    Complex c1(1, 2);
    static Complex c2(1, 2);
}
int main() {

}
  • c1便是所谓stack object,其生命在作用域(scope)结束之际介绍。这种作用域内的object,又称为auto objects,因为它会被”自动“清理。
  • c2便是所谓static object,其生命在作用域(scope)结束之后仍然存在,直到整个程序结束。
  • c3便是所谓global object,其生命在整个程序结束之后才结束。你也可以把它视为一种static object,其作用域是整个程序。

heap objects的生命周期

class Complex {

};

{
    Complex* p = new Complex;
    delete p;
}
  • p所指的便是heap object,其生命在它被delete之际结束。
class Complex {

};

{
    Complex* p = new Complex;
}
  • 以上出现内存泄露(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不见p(也就没有机会delete p)

new:先分配memory,再调用ctor

Complex* pc = new Complex(1, 2);

编译器转化为:

Complex* pc;

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

delete:先调用dtor,在释放memory

String* ps = new String("Hello");
delete ps;

编译器转化为:

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

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

动态分配所得的array

以上两部分略,这两部分侯捷老师主要为说明的是delete和delete[]的区别。其实就是,开辟的数组就用delete[],否则可能会内存泄露,为什么是可能?因为:

int* p = new int[1];

复习String类的实现过程

略,同三大函数:拷贝构造,拷贝复制,析构部分。

版权声明:本文为博主原创文章,未经博主允许不得转载。

极客班GeekBand - C++面向对象高级开发 - 2

标签:

原文地址:http://blog.csdn.net/lionpku/article/details/47106891

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!