极客班GeekBand - C++面向对象高级开发 - 二
极客班GeekBand - C++面向对象高级开发 - 2
极客班GeekBand - C++面向对象高级开发 - 2
- 极客班GeekBand - C面向对象高级开发 - 2
- 讲师 - 侯捷
- 复习Complex类的实现过程
- 三大函数拷贝构造拷贝复制析构
- 栈堆与内存管理
- Stack VS Heap
- stack objectsstatic local objectsglobal objects的生命期
- heap objects的生命周期
- new先分配memory再调用ctor
- delete先调用dtor在释放memory
- 动态分配所得内存块memory blockin VC
- 动态分配所得的array
- 复习String类的实现过程
讲师 - 侯捷
复习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类的实现过程
略,同三大函数:拷贝构造,拷贝复制,析构部分。
版权声明:本文为博主原创文章,未经博主允许不得转载。