Classes 根据是否包含指针成员(指向动态内存(堆内存))可以分为:
Class without pointer member(s): complex
class complex{public: complex (double r = 0, double i = 0): re (r), im (i) { } complex& operator += (const complex&); complex& operator -= (const complex&); complex& operator *= (const complex&); complex& operator /= (const complex&); double real () const { return re; } double imag () const { return im; }private: double re, im;};
Class with pointer member(s): string
class String{public: String(const char* cstr=0); String(const String& str); String& operator=(const String& str); String::~String(){ delete[] m_data;} char* get_c_str() const { return m_data; }private: char* m_data;};
自然,对于包含有指针并使用了动态内存的类具有更高的复杂性,不能使用编译器默认提供的拷贝构造函数、拷贝赋值和析构函数,需要程序员自己重写。
对于类的对象自然也可以是栈对象,也可以是堆对象。
{ String s1("hello"); // 栈对象}// 当作用域结束时,自动调用~String()String *ps = new String("hello");delete ps;编译器自动转化为以下操作:String::~String(); //先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); //然后再释放自己所占的堆空间,底层调用的是C的free(ps)
对于包括有指针(指向堆内存)的堆对象,相当于使用了双重堆内存。
new的流程:
String *ps = new String("Hello");
编译器自动转化为以下操作:
String::~String(); // 先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); // 然后再释放自己所占的堆空间,底层调用的是C的free(ps)
指针ps位于栈上(&ps),其值是一个堆内存地址。
调用构造函数String("Hello"),m_data指向"Hello":
delete流程:
delete ps; // 手动释放
编译器自动转化为以下操作:
String::~String(); // 先调用析构函数,将对象中指针变量指向的空间释放掉operator delete(ps); // 然后再释放自己所占的堆空间,底层调用的是C的free(ps)
先~String();,然后:delete(ps);
arrary new:
delete p:
先~String(); 左边的一块堆内存释放掉了。
然后 delete(p); 右边的一块堆内存只释放掉了第一部分。
arrary delete: delete[] p :
先~String(); 左边的一块堆内存释放掉了。
然后 delete[] (p); 其中的[]就是告诉编译器,需要释放的是多份。
ref : C++面向对象高级编程(侯捷)
https://www.bilibili.com/video/BV14s411E772
-End-