本章主要講解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函式 讓執行緒一開始...