構造、析構、賦值運算
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...