c primer第十二章讀書筆記

2021-07-28 15:01:40 字數 3504 閱讀 7543

本章主要講解new運算子在各種情況下的使用注意事項。

c++使用new和delete運算子來動態控制記憶體。

一、關於靜態成員

(1)靜態成員屬於類,不屬於物件,即在多個物件中只有乙個靜態成員物件副本。

(2)靜態資料成員在類中宣告,在包含類方法的檔案中初始化。但如果靜態成員是const整型型別或者列舉型別,則可以在類宣告中初始化。

(3)靜態成員函式由於沒有this指標,因此只能訪問靜態成員。物件要通過作用域限定符來呼叫靜態成員方法。

在自定義類string要考慮淺拷貝與深拷貝的問題,下面對自定義類中預設方法做個分析,要對函式做深拷貝和淺拷貝的考慮。

二、關於自定義類預設生成的函式

預設建構函式、預設析構函式、拷貝建構函式、賦值運算子、位址運算子

(1)預設建構函式:

帶引數的建構函式也可以是預設建構函式,只要所有的引數都有預設值。

在建構函式中使用new分配記憶體,必須在相應的析構函式中使用delete來釋放記憶體。

(2)拷貝建構函式

拷貝函式呼叫的三種情況。

新建乙個物件並初始化化同類現有物件時,會呼叫拷貝建構函式。

string s1(s2);

string s1 = s2;

string s1 = string(s2);

string *p2 = new

string(s2);

當函式按值傳遞時,會呼叫拷貝函式

返回區域性物件時,會呼叫拷貝建構函式。

由於按值傳遞都將呼叫拷貝建構函式,因此應該按照引用來傳遞,提高效率。

預設拷貝建構函式逐個複製資料成員,複製的是成員的值,這樣就會造成淺拷貝。

淺拷貝的指的是有複製資料成員指標的值,但沒有為分配空間,造成兩個指標指向同一塊記憶體,使得析構函式

對這塊記憶體釋放了兩次,因此對拷貝建構函式進行過載。

(3)賦值運算子

string s1 =s2;
關於這句**可能有兩種使用步驟:

一是初始化,直接呼叫拷貝建構函式。二是先呼叫拷貝建構函式,然後使用賦值運算子。

在自定義型別string中,關於賦值運算子要實現深拷貝。

三、在建構函式中使用new的注意事項:

1- 如果建構函式使用new來初始化指標成員,則應該在析構函式中使用delete

2- new對於delete ,new [ ] 對應delete [ ]

3- 多個建構函式中必須使用相同的方式使用new,但可以在乙個建構函式中使用new,在另乙個建構函式中將指標成員置空(c++新的特性使用nullptr表示空指標)

四、有關返回物件的說明

(1)返回指向const物件的引用,(不會呼叫拷貝建構函式)旨在提高效率。

(2)返回指向非const物件的引用,這裡主要考慮對流運算子的過載(<< 或者 >>).

(3)返回物件,不能返回區域性的引用。

(4)返回const物件,防止在if判斷中將==寫成=,改變物件的值,保護資料。

五、析構函式呼叫的情況

(1)物件是動態,執行完定義該物件的程式是,將呼叫物件的析構函式。

(2)如果物件時靜態(外部、靜態(外部)或者來著命名空間),程式解釋時,呼叫析構函式

(3)如果物件時new建立的,顯式呼叫delete刪除物件,將呼叫析構函式,否則該物件的析構函式不會被呼叫。

六、關於placement new 運算子

palacement new

在已有的記憶體上分配空間,不分配空間,只是建構函式的呼叫。

void * operator

new(size_t size,void *p)

cahr buffer[1024]

test *p2 = new(buffer) test(200);//operator new(sizo_t ,void *p)

cout

<< p2->n_ string.h

#ifndef _string_h_

#define _string_h_

#include

using

namespace

std;

class string

;#endif //_string_h_

string.cpp

#include 

#include

#include "stringbad.h"

using

namespace

std;

int string::num_strings = 0;

string::string(const

char *s)

string::string(const string &s)

string & string::operator=(const string & s)

delete str;

len = s.len;

str = new

char[len + 1];

strcpy(str,s.str);

return *this;

}string & string::operator=(const

char *s)

string::string()

string::~string()

bool

operator

<(const string &s1,const string &s2)

bool

operator>(const string &s1,const string &s2)

bool

operator==(const string &s1,const string &s2)

char & string::operator(int i)

const

char & string::operator(int i) const

ostream & operator

<<(ostream &out,const string &st)

istream &operator>>(istream &in,string &st)

while(in && in.get() != '\n')

continue;

return in;

}int string::howmany()

main.cpp

#include 

#include "stringbad.h"

using

namespace

std;

void callme1(string &);

void callme2(string );

int main()

void callme1(string &rsb )

void callme2(string rsb)

C primer 第十二章筆記 初稿

區域性static物件,類的static資料成員及定義在函式之外的變數,都儲存在靜態記憶體中 函式內的非static物件儲存在棧中 動態分配的物件儲存在堆中 執行時分配記憶體 shared ptr 注 內建指標與智慧型指標不存在隱式轉換,必須直接初始化。當使用get 方法時,很容易產生釋放物件空間的...

《重構》讀書筆記12(第十二章完結)

互為逆重構。子類中有重複 就可以考慮上移到父類,而父類中的函式如果只與個別子類有關就可以下移。互為逆操作。子類有類似字段可以考慮上移到父類,父類的字段只在被個別子類用到可以考慮下移。其實和函式上移差不多,只是建構函式比較特殊專門拿出來說。互為逆重構。在用型別碼來區分時不妨引入子類,兩種引入方式 一種...

APUE讀書筆記 第十二章 執行緒控制

初始化 銷毀屬性物件,每個屬性都有 從屬性物件中獲取屬性值 設定屬性值兩個個函式 實現執行緒分離的兩種方法 1 使用pthread detach函式 2 修改pthread attr t結構中的detachstate屬性 使用pthread attr setdetachstate函式 讓執行緒一開始...