2016-09-16 61 views
0

我正在學習C++並閱讀C++的一本書。C++中的虛擬類的向量

第9.2.1節中,這本書說

vector<Shape> vs;    # is bad, 
vector<Shape*> vps;    # is better, and 
vector<unique_ptr<Shape>> vups; # is OK. 

我的問題是,爲什麼 「矢量<形狀> VS」;不被接受,並且「矢量< unique_ptr <形狀> > vups;」是最好的?你能澄清一下嗎?

這裏的形狀類是一個虛擬類。在前一章中,Circle類和Triangle類已被定義爲從Shape派生。 Circle類對象和Triangle類對象旨在存儲在容器中。

回答

1

vector容器擁有其中的每個對象,具體構造對象成爲矢量的一部分。由於您無法構建Shape以進入矢量,因此無法使用std::vector<Shape>。嘗試將一個對象插入到該向量中,但無法完成。

另一方面,指向從Shape派生的任何類的實例的指針都可以轉換爲Shape*,並且您可以複製無問題的指針。所以這很好:

vector<Shape*> vps; 
vps.insert(new Circle()); 

類似地,unique_ptr s是多態的。所以你可以構造一個unique_ptr<Shape>,它指向一個從Shape派生的類的實例。

但是,您無法制作Shape,它是從Shape派生的類的實例。所以vector<Shape>是一個非首發。

看到它的另一種方法是查看矢量將分配的空間。對於Shape*的矢量,它將分配足夠的空間來容納Shape*,並且該指針可以包含從Shape派生的類的實例的指針,沒有問題。

對於unique_ptr<Shape>的載體,將分配足夠的空間來容納一個unique_ptr<Shape>,並且能夠保持一個唯一的指針Shape指向從Shape,沒問題派生的類。

但是vector<Shape>會發生什麼情況。這分配足夠的空間來容納Shape。但是,如果我們試圖存儲從Shape派生的類,我們該怎麼辦?我們無法用這個空間做任何事情!派生類的實例通常比其基類的實例大,所以這樣的向量對我們來說將再次無用。