本篇內(nèi)容主要講解“C++中默認(rèn)操作怎么定義”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“C++中默認(rèn)操作怎么定義”吧!
專業(yè)從事企業(yè)網(wǎng)站建設(shè)和網(wǎng)站設(shè)計(jì)服務(wù),包括網(wǎng)站建設(shè)、國(guó)際域名空間、雅安服務(wù)器托管、企業(yè)郵箱、微信公眾號(hào)開(kāi)發(fā)、微信支付寶小程序開(kāi)發(fā)、app軟件定制開(kāi)發(fā)、軟件開(kāi)發(fā)、等服務(wù)。公司始終通過(guò)不懈的努力和以更高的目標(biāo)來(lái)要求自己,在不斷完善自身管理模式和提高技術(shù)研發(fā)能力的同時(shí),大力倡導(dǎo)推行新經(jīng)濟(jì)品牌戰(zhàn)略,促進(jìn)互聯(lián)網(wǎng)事業(yè)的發(fā)展。
C.21:默認(rèn)操作要定義就全定義,要禁止就全禁止
特殊的成員函數(shù)包括構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),拷貝賦值運(yùn)算符,移動(dòng)構(gòu)造函數(shù),移動(dòng)賦值運(yùn)算符和析構(gòu)函數(shù)。
譯者注:這些函數(shù)都具有管理數(shù)據(jù)成員生命周期的責(zé)任,因此實(shí)現(xiàn)還是禁止都需要統(tǒng)一。
特殊函數(shù)的語(yǔ)義緊密相關(guān),如果一個(gè)需要聲明,可能其他的也需要考慮。
定義除默認(rèn)構(gòu)造函數(shù)之外的所有特殊函數(shù),即使采用=default或者=delete的形式,將會(huì)抑制隱式聲明移動(dòng)構(gòu)造函數(shù)和移動(dòng)賦值運(yùn)算符。聲明移動(dòng)構(gòu)造函數(shù)或者移動(dòng)賦值運(yùn)算符,即使采用=default或者=delete的形式,也會(huì)導(dǎo)致隱式生成的拷貝構(gòu)造函數(shù)或者拷貝賦值運(yùn)算符被定義為=delete。因此,一旦任何一個(gè)特殊函數(shù)被聲明,其他的都應(yīng)該被聲明以避免多余的效果。例如將所有的潛在移動(dòng)操作都被變成代價(jià)高昂的拷貝操作,或者令這個(gè)類變成只移動(dòng)的。
struct M2 { // bad: incomplete set of default operations
public:
// ...
// ... no copy or move operations ...
~M2() { delete[] rep; }
private:
pair* rep; // zero-terminated set of pairs
};
void use()
{
M2 x;
M2 y;
// ...
x = y; // the default assignment
// ...
}
假設(shè)析構(gòu)函數(shù)需要那個(gè)“特殊模式”(這里是釋放內(nèi)存),那么(默認(rèn)的,譯者注)拷貝和移動(dòng)賦值(都會(huì)隱性銷毀對(duì)象)正確動(dòng)作的可能性就會(huì)很低。
這就是眾所周知的"5特殊函數(shù)規(guī)則"或者"6特殊函數(shù)規(guī)則",不同之處在于是否將默認(rèn)構(gòu)造函數(shù)算進(jìn)來(lái)。
Note(注意)
如果需要默認(rèn)操作的默認(rèn)實(shí)現(xiàn)(例如定義了其他非默認(rèn)的),通過(guò)=default表示你是有意那么做的。如果不想要默認(rèn)操作,通用=delete抑制它的產(chǎn)生。
譯者注:例如,如果定義了某種形式的構(gòu)造函數(shù),編譯器就不會(huì)生成默認(rèn)的構(gòu)造函數(shù)。
Example, good(示例)
如果需要聲明析構(gòu)函數(shù)就直接定義為virtual,這個(gè)做法可以作為默認(rèn)。為了避免抑制隱式的移動(dòng)操作,它們也必須被聲明。為了避免類成為只移動(dòng)(和拷貝禁止)類型,拷貝操作也必須聲明:
class AbstractBase {
public:
virtual ~AbstractBase() = default;
AbstractBase(const AbstractBase&) = default;
AbstractBase& operator=(const AbstractBase&) = default;
AbstractBase(AbstractBase&&) = default;
AbstractBase& operator=(AbstractBase&&) = default;
};
為了避免由于規(guī)則C.67產(chǎn)生的分歧,也可以將拷貝和移動(dòng)運(yùn)算符定義為刪除的。
class ClonableBase {
public:
virtual unique_ptr clone() const;
virtual ~ClonableBase() = default;
ClonableBase(const ClonableBase&) = delete;
ClonableBase& operator=(const ClonableBase&) = delete;
ClonableBase(ClonableBase&&) = delete;
ClonableBase& operator=(ClonableBase&&) = delete;
};
只定義移動(dòng)操作或者拷貝操作產(chǎn)生的效果相同,但是應(yīng)該明確地為每個(gè)特殊函數(shù)說(shuō)明目的以便讓讀者更容易理解。
編譯器會(huì)強(qiáng)制執(zhí)行本規(guī)則的大部分,理想情況會(huì)對(duì)任何違反發(fā)出警告。
Note(注意)
強(qiáng)烈反對(duì)一個(gè)具有析構(gòu)函數(shù)的類依靠隱式產(chǎn)生的拷貝操作。
同時(shí)寫6個(gè)特殊成員函數(shù)容易發(fā)生錯(cuò)誤。注意以下代碼中的參數(shù)類型。
class X {
public:
// ...
virtual ~X() = default; // destructor (virtual if X is meant to be a base class)
X(const X&) = default; // copy constructor
X& operator=(const X&) = default; // copy assignment
X(X&&) = default; // move constructor
X& operator=(X&&) = default; // move assignment
};
小錯(cuò)誤(例如拼寫錯(cuò)誤,落了const,用了&而不是&&,或者落了某個(gè)特殊成員函數(shù))會(huì)引起錯(cuò)誤或警告。為了避免無(wú)聊的代碼和可能的錯(cuò)誤,努力踐行"0特殊函數(shù)"原則。
Enforcement(實(shí)施建議)
(簡(jiǎn)單)類應(yīng)該要么聲明(哪怕是通過(guò)=delete)所有的特殊函數(shù),要么一個(gè)也不聲明。
到此,相信大家對(duì)“C++中默認(rèn)操作怎么定義”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!