這是一個問題,當應用到子類關於與C++ 11引入了delete操作符的新的意義的最佳實踐覆蓋繼承父的虛擬方法。
背景:
每標準,第一使用情況中引用是明確禁止調用函數對於某些類型的,其中轉化率,否則將隱式如從最新C++11 standard draft§8.4.3的例子:
struct sometype {
sometype() = delete; // OK, but redundant
some_type(std::intmax_t) = delete;
some_type(double);
};
上面的例子很清楚,有目的。但是,下面的示例中,新操作符被覆蓋並通過將其定義爲刪除而被阻止開始,我開始考慮後來在問題部分中指出的其他場景(以下示例來自C++11 standard draft的§8.4.3):
struct sometype {
void *operator new(std::size_t) = delete;
void *operator new[](std::size_t) = delete;
};
sometype *p = new sometype; // error, deleted class operator new
sometype *q = new sometype[3]; // error, deleted class operator new[]
問:
通過這種思想繼承的延伸,我很好奇,就以下使用示例是一個清晰而有效的用例其他的想法,或者如果它是不明確的濫用的新增功能。請提供您的答案的理由(提供最有說服力的推理的例子將被接受)。在下面的例子中,設計試圖通過讓庫的第二版本繼承第一版本來維護兩個版本的庫(該庫需要被實例化)。這個想法是允許對第一個庫版本的錯誤修復或更改自動傳播到第二個庫版本,同時允許第二個庫版本只關注與第一個版本的差異。棄用第二庫版本的函數,delete運算符是用來呼叫禁止,以重寫的功能:
class LibraryVersion1 {
public:
virtual void doSomething1() { /* does something */ }
// many other library methods
virtual void doSomethingN() { /* does something else */ }
};
class LibraryVersion2 : public LibraryVersion1 {
public:
// Deprecate the doSomething1 method by disallowing it from being called
virtual void doSomething1() override = delete;
// Add new method definitions
virtual void doSomethingElse() { /* does something else */ }
};
雖然我可以看到很多好處,這樣的做法,我覺得我傾向於更傾向於思想這是對該功能的濫用。我在上面的例子中看到的主要缺陷是經典的「is-a」繼承關係被打破。我讀過很多文章,強烈建議不要使用繼承來表達「一種是一種」關係,而是使用包含函數的組合來清楚地標識類的關係。儘管下面經常被忽視的例子需要更多的努力來實現和維護(關於爲這段代碼編寫的行數,由於每個繼承函數都必須公開可用,必須由繼承類明確地調用),使用如上所述的刪除在很多方面非常相似:
class LibraryVersion1 {
public:
virtual void doSomething1() { /* does something */ }
virtual void doSomething2() { /* does something */ }
// many other library methods
virtual void doSomethingN() { /* does something */ }
};
class LibraryVersion2 : private LibraryVersion1 {
// doSomething1 is inherited privately so other classes cannot call it
public:
// Explicitly state which functions have not been deprecated
using LibraryVersion1::doSomething2();
// ... using (many other library methods)
using LibraryVersion1::doSomethingN();
// Add new method definitions
virtual void doSomethingElse() { /* does something else */ }
};
非常感謝您的回答,並深入瞭解此潛在用例的刪除。
我不認爲'虛擬無效doSomething1()倍率=刪除;'是合法的。有什麼辦法'((LibraryVersion1 *)(新LibraryVersion2)) - > doSomething1()'做什麼? –
按我的理解,即使投給LibraryVersion1,刪除的功能仍然試圖通過LibraryVersion2被稱爲給出的倍率,導致代碼編譯失敗。正如我的問題所指出的那樣,這是「is-a」關係被打破的地方,但它肯定會按預期強制執行棄用。 – statueuphemism
fresh:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf – qPCR4vir