簡體   English   中英

與組合相比,為什么私有繼承會增加有人破壞我的代碼的可能性?

[英]Why does private inheritance increase the probability, as compared to composition, that someone will break my code?

本文的作者指出

“通常,您不希望訪問太多其他類的內部結構,並且私有繼承為您提供了一些額外的功能(和責任)。但是私有繼承並不是邪惡的;維護起來更昂貴,因為它增加了有人更改將破壞您的代碼的可能性的可能性。”

假定以下代碼,其中Car私下從Engine繼承:

#include <iostream>
using namespace std;

class Engine
{
    int numCylinders;
    public:
    class exception{};
    Engine(int i) { if( i < 4 ) throw exception(); numCylinders = i; }
    void start() { cout << "Engine started " << numCylinders << " cylinders" << endl; }
};

class Car : private Engine          
{    
    public:
    Car(int i) : Engine(i) {}
    using Engine::start;
};

int main()
{
    try
    {
        Car c(4);
        c.start();
    }
    catch( Engine::exception& )
    {
        cout << "A Car cannot have less than 4 cylinders" << endl;
    }
}

我的問題是: Car如何通過設置私有繼承且基類中沒有受保護成員的方式,例如設置少於4個汽缸的Engine來破壞此代碼?

繼承比成員關系引入更緊密耦合的一種方法是,將派生類和基類的名稱空間混合在一起。 因此,在派生類的上下文中,名稱的含義取決於基類引入的名稱,並且具有通常的重寫/隱藏效果。 基類的更改可能會對派生類中的代碼產生影響,這些影響不一定很明顯,或者會立即產生有用的診斷信息。 相反,如果成員對象的界面發生變化,那么最容易破壞的將是實際提及該成員對象的代碼。

我認為問題不是Car可以破壞您的Engine代碼,而是通過更改Engine可以破壞您的Car代碼。 繼承表示的組合要比組成緊密得多,因此Engine中的更改更有可能破壞從其繼承而不是包含它的類。 對於C ++,通過使Car包含Engine指針或smart指針,可以實現更為寬松的耦合。

我看不到Car可以設置Engine :: numCylinders(至少不是沒有訪問原始內存的骯臟技巧)。 本文中的示例使用受保護的方法,使用私有成員。

順便說一句:本文從“在可能的情況下使用合成”開始-一輛汽車一個引擎,但不是引擎。 A衍生自B時,通常表示AB。

該文章的作者,在之前的點,指的是一些使用私有繼承的“缺點”的位置

  • 如果您希望每輛車包含多個引擎,則需要簡單組合變體
  • 私有繼承變體可以引入不必要的多重繼承
  • 私有繼承變體允許Car的成員將Car *轉換為Engine *
  • 私有繼承變量允許訪問基類的受保護成員
  • 私有繼承變體允許Car覆蓋Engine的虛擬功能
  • 私有繼承變體使Car的start()方法稍微簡單一些(從20個字符到28個字符),該方法可以簡單地調用Engine的start()方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM