c 學習筆記十七

2022-08-18 04:09:14 字數 4480 閱讀 1303

構造、析構、賦值運算

c++會為乙個空類宣告乙個copy建構函式,乙個copy assignment操作符和乙個析構函式

如果沒有宣告建構函式,還會生成乙個default建構函式

示例**如下:

class empty;

等同於class empty

//copy建構函式

empty(const empty& rhs)

//析構函式 non-virtual

~empty()

//copy assignment操作符

empty& operator=(const empty& rhs)

};編譯器會產生出

empty el;//default建構函式

empty e2(e1);//copy建構函式

e2=e1;//copy assignment操作符

copy建構函式和copy assignment操作符,編譯器建立的版本只是單純地將源物件的每乙個

non-static成員變數拷貝到目標物件

示例**如下:

template

class namedobject;

由於namedobject函式沒有宣告copy建構函式和copy assignment操作符,編譯器會自動建立

具體用法如下:

namedobjectno1("sample prime number",2);

//呼叫copy建構函式,以no1.namevalue和no1.objectvalue為no2的兩個屬性符值

namedobjectno2(no1);

copy assignment操作符

示例**如下:

template

class namedobject;

使用場景:

std::string newdog("persephone");

std::string olddog("satch");

namedobjectp(newdog,2);

namedobjects(olddog,36);

p=s;

如果某物件是獨一無二(不允許複製),就需要拒絕編譯器自動生成的函式

即將copy構造器和copy assignment操作符宣告為private

即使這樣member函式和friend函式還是會呼叫private函式,因此還要不去定義private函式

可以從標準程式庫實現**中檢視如ios_base basic_ios和sentry

示例**如下:

class homeforsale;

如果想拷貝homeforsale物件編譯器會阻止,如果是在member函式和friend函式中呼叫

聯結器會阻止

如果想在編譯時阻止,可以用以下方法實現

class uncopyable

~uncopyable(){}

private:

uncopyable(const uncopyable&);

uncopyable& operator=(const uncopyable&);

};//目標函式繼承uncopyable函式

//此時不用宣告copy建構函式和copy assignment操作符

class homeforsal: private uncopyable;

為多型基類宣告virtual析構函式

示例**如下:

class timekeeper;

class atomicclock:public timekeeper; //原子鐘

class waterclock:public timekeeper; //水鐘

class wristwatch:public timekeeper;//腕表

需要乙個factory函式返回乙個計時物件

timekeeper* gettimekeeper();//返回乙個指向timekeeper派生類的動態物件

timekeeper* ptk=gettimekeeper();

delete ptk;//釋放資源

注:gettimekeeper返回的指標指向乙個derived class(派生類)物件,這個物件由乙個

base class指標被刪除,而base class(timekeeper)有個non-virtual析構函式,執行時

物件的derived部分沒有被銷毀(derived class的析構函式未執行)

解決辦法如下:

class timekeeper;

timekeeper* ptk=gettimekeeper();

delete ptk;

如果乙個函式不打算用作base class時,就不需要使其建構函式為virtual

避免析構函式中報異常

示例**如下:

class widget//假設這裡出現異常

};void dosomething() //v在這裡被自動銷毀

//聯接資料庫

class dbconnection

//用來管理dbconnection

class dbconn

private:

...dbconnection db;

};為了防止在dbconn的析構函式中呼叫close()方法發生異常

處理方法如下:

dbconn::~dbconn()

catch(...)

}//採用獨立函式處理異常

class dbconn

~dbconn()

catch()}}

private:

dbconnection db;

bool closed;

}不在建構函式和析構函式中呼叫virtual函式,回為這類呼叫從不下降至derived class

示例**如下:

//所有交易的base class

class tranxaction;

//base class 實現

transaction::transaction()

//子類

class buytransaction:public transaction;

//子類

class selltransaction:public transaction;

當執行buytransaction b;時首先transaction建構函式會更早被呼叫

替換方法

class transaction;

transaction::transaction(const std::string& loginfo)

class buytransaction:public transaction

...private:

static std::string createlogstring(parameters);

};讓operator=返回乙個reference to *this

賦值int x,y,z;

x=y=z=15;

x=(y=(z=15));

示例**如下:

class widget

widget& operator=(int rhs)

}在operator=中處理"自我賦值"

//物件在賦值給自已時

class widget;

widget w;

...w=w;

示例**如下:

//儲存乙個指標指向一塊動態分配的記憶體

class bitmap;

class widget;

//operator=實現**

widget& widget::operator=(const widget& rhs)

更好的實現,即處理異常安全,又處理自我賦值

class widget;

widget& widget::operator=(const widget& rhs)

複製物件時注意其每一成員

示例**如下:

void logcall(const std::string& funcname);

class customer;

customer::customer(const customer& rhs):name(rhs.name)

customer& customer::operator=(const customer& rhs)

當customer 中新增乙個成員時,copy建構函式和copy assignment都要新增

如果是子類

prioritycustomer:public customer;

prioritycustomer::prioritycustomer(const prioritycustomer& rhs)

:customer(rhs), //呼叫base class 的copy建構函式

priority(rhs.priority)

prioritycustomer& prioritycustomer::operator=(const prioritycustomer& rhs)

Oracle學習筆記(十七)

103 date,timestamp,interval 這三個是oracle 處理時間方面的型別。從字面上面,就可以很清楚的明白這其中的區別。date 是正常的時間。timestamp 是時間戳。而interval 則是表示一段時間。覺得分割的好細緻 還有一點需要明白的是,在資料庫中,儲存的時間無論...

opencv python學習筆記十七

20 影象金字塔 高斯金字塔 拉普拉斯金字塔 所用函式 defpyrdown src,輸入影象 dst none,輸出影象 dstsize none,輸出影象的大小 bordertype none 影象邊界的處理方式 defpyrup src,dst none,dstsize none,border...

Effective C 學習筆記 《十七》

其實這一點講的要點比較隱晦,在平時程式設計的時候很難發現這個問題,但要是不注意卻又是乙個隱患,所以對這個要點的理解更應該養成是一種程式設計習慣。首先書上給了一段 作為例子 int priority void processwidget std tr1 shared ptrpw,int priorit...