C 物件導向高階程式設計 三 基礎篇

2021-10-01 17:45:58 字數 3552 閱讀 9026

概要一.拷貝構造

二.拷貝賦值

三.重寫操作符

四.生命週期

本節主要介紹 big three 即析構函式,拷貝建構函式,賦值拷貝函式,前面主要圍繞不帶指標的class complex本節中主要圍繞帶指標的string類

前面我說過如果你建立的類不帶有指標,那麼多半你可以不用寫析構函式,但是如果你建立了乙個帶指標的類,那麼你必須重寫big three

建立乙個類

class

string

private

:

char* m_data; //

由於帶有指標 ,所以需要重寫析構函式,拷貝構造,賦值拷貝

};

一.拷貝構造如下操作會呼叫拷貝建構函式

string a;
它的實現為

inline

string::string(

const

char* cstr) //

拷貝構造

else

}

這個大家都應該理解

二.拷貝賦值

下面做賦值拷貝操作

string a;

string b;

s1 = s2;

若果我們使用編譯器自帶的賦值拷貝就會發生下面的現象

這樣操作會產生野指標,  因為a和b同時指向 hello  ,沒人指向world

同時如果a和b同時指向同一塊記憶體,如果你刪掉a的話  b指向的記憶體也會被刪掉,這可不是我們想要的

所以我們必須重寫賦值拷貝函式,下面是正確的賦值拷貝函式

inline

string& string::operator=(const string& str) //

拷貝賦值

賦值拷貝的三個步驟: 1.釋放自身記憶體 2.建立新記憶體 3.copy

注意上面的紅色部分

三.重寫操作符

因為string類是你新建立的,所有cout不識別你自己建立的類,所以你要重寫乙個<<

#include using

namespace

std;

ostream& operator

<

如果寫成成員函式呼叫的時候是這樣 c1 << cout 是不是很難接受啊

四.生命週期

下面我來介紹乙個記憶體管理

1.stack(棧),是存在於某作用域 (scope) 的一一塊記憶體空間 (memory space)。例如當你呼叫函式,函式本身即 會形成乙個 stack 用來放置它所接的引數,以及返回位址

2.heap, system heap,是指由作業系統提供的 一塊 global 記憶體空間,程式可動態分配 (dynamic allocated) 從某中獲得若干區塊 (blocks)

例如

string s1;//

stack

string s2 = new string("

world

");//

動態分配 heap

static complex c2(1,2); //

static

stack 棧 的生命週期在作用域結束之際結束.自動清理

heap 堆 的生命週期在他被呼叫delete之際結束

static 靜態物件 生命週期會一直存在帶程式結束之際

global 全域性物件 其生命在整個程式結束之後 才結束。你也可以把它視為一種 static object,其作用域 是「整個程式」

五.記憶體管理

先說一下new 和 delete 的呼叫過程

1. new:先分配 memory, 再呼叫 ctor 

complex* pc = new complex(1,2);
編譯器會把它翻譯成

void* mem = operator

new( sizeof(complex) ); //

分配記憶體,其內部呼叫malloc

pc = static_cast(mem); //轉型

pc->complex::complex(1,2); //構造

函式 pc->complex::complex(1,2);

2. delete:先呼叫 dtor, 再釋放 mxemory 

complex* pc = new complex(1,2

);...

delete pc;

編譯器轉化為

complex::~complex(pc); //

析構函式

operator

delete(pc); //

釋放記憶體 其內部呼叫feee()

下面是說一下動態分配所得的記憶體塊以vc編譯器為例

debug版 complex類內涵兩個double型成員變數(實部虛部)

每格4位元組

是不是感到有些驚訝,在debug版下 我們僅new complex() 到底給我們帶來多少的記憶體呢

頭部和尾部(紅色部分)的00000041是 cookie 是兩個4位元組記憶體  cookie負責標記記憶體 最後一位的1是代表獲得記憶體     如果最後一位是0**記憶體  4*2 = 8bit

灰色部分是vc分期記憶體是賦予的每塊debug記憶體都會有這塊記憶體 4*8 + 4 = 36bit

綠色部分是我們的conplex       8bit

青色部分是補位部分,因為vc下每一塊記憶體必須是16的倍數

那麼我們new乙個complex系統應該分配給 (4*2) + 36 + 8 + (4*3 補位) = 64bit

那麼非debug版

下面我們來看一下帶指標的string類

debug版

非debug版

可見指標占用的記憶體小一些

總結1.帶有指標的class必須重寫big three這是乙個非常良好的習慣

2.指標更省記憶體

如有不正確的地方請指正

參照《侯捷 c++物件導向高階程式設計》

C 物件導向高階程式設計 四 基礎篇

一.static 二.模板類和模板函式 三.namespace 一.static 靜態成員是 類級別 的,也就是它和類的地位等同,而普通成員是 物件 例項 級別 的.類級別的成員,先於該類任何物件的存在而存在,它被該類所有的物件共享.static 1.修飾變數,該變數時全域性變數,其實靜態變數不歸屬...

C 物件導向高階程式設計 一 基礎篇

概要 知識點1 建構函式與析構函式 知識點2 引數與返回值 知識點3 const 知識點4 函式過載 要與重寫區分開 知識點5 友元 先以c 的兩大經典class complex 不含指標,string 含指標 之一 complex 複數類 做例子.ifndef complex hpp 防止標頭檔案...

物件導向高階程式設計

相同class的各物件互為友元 class complex int func const complex param private double re,im string inline string string const char cstr 0 else inline string strin...