2013-01-07 72 views
0

我有一個通用的鏈接列表,與各種類型的數據一起工作,包括對象和指向對象的指針等,但我在使用列表中的對象時遇到問題派生自抽象類C++鏈接列表 - 插入對象

我有一個抽象類叫車和2類,是卡爾和卡車,我可以做這樣的事情:

list<vehicle> lv; 

vehicle * v1; 
vehicle * v2; 

v1 = new carr; 
v2 = new truck; 

cin >> *v1 >> *v2; 

//But when I try to insert in the list 

lv.insertEnd(*v1); 

我有錯誤:

不能分配的抽象對象type'vehicle'

而編譯器顯示錯誤發生在我寫的部分的鏈接列表代碼的insertEnd方法中:

newNode->item = new Item; 

這是一個項目的一部分,我需要一個車輛列表和車輛可以carrs,卡車等我有一組指示器指針實現的車輛,但我試圖做到這一點與車輛清單。

你能幫我嗎?

編輯: 該項目是在我的鏈接列表,我會告訴我的insertEnd方法:

template <class Item> 
void list<Item>::insertEnd(const Item& item) 
{ 
    node<Item> *newNode= new node<Item>; 

    newNode->item = new Item; 
    *(newNode->item) = item; 
    newNode->next = 0; 

    if(head == 0) 
    { 
     head = newNode; 
     tail = newNode; 
     _size++; 
    } 
    else 
    { 
     novoNo->prev = tail; 
     tail->next = newNode; 
     tail = newNode; 
     _size++; 
    } 
} 
+0

什麼是「項目」? – paul23

+1

您正在嘗試將'vehicle'實例插入到容器中。但它很抽象。回想一下,容器擁有自己的元素,從而複製他們的輸入。閱讀關於切片。 –

+0

你想製作一個指針列表或對象列表嗎?如果'insertEnd'採用'vehicle',那麼它不能採用'carr'或'truck',而只能採用'vehicle'的實例。 (不幸的是,在C++中創建多態集合非常令人惱火,首先,沒有簡單的方法可以通過給定引用或指針來複制對象)。 –

回答

2

你需要在這種情況下使用指針,更好的辦法是使用智能指針。

std::list<std::shared_ptr<vehicle> > lv; 

在你list<vehicle> lv;lv只包含vehicle類型的對象,lv.insertEnd(*v1);你的對象車輛類型,是不允許的車輛是抽象類。

+0

謝謝我會試試這個。如果我不行這不是一個大問題,我已經實現了指針指針並且它正在工作,唯一不方便的是我必須調整大小。 – wormwood87

5

您正試圖在您的鏈接列表中按值存儲項目。按值使用項目可以中斷多態:只有指針或引用是多態的。

這是你看到的錯誤的原因是你在這裏取消你的指針:lv.insertEnd(*v1)。以這種方式傳遞一個值將導致C++使用insertEnd中指定類型的拷貝構造函數來使insertEnd函數中的對象成爲對象(請檢查您的代碼:參數類型爲insertEnd肯定是您指定的類型模板 - 這裏是vehicle)。通過傳值,您告訴您的代碼將整個v1複製到insertEnd內的新對象中。這個分崩離析,因爲vehicle是一個抽象類:它的拷貝構造函數不能用來創建一個功能齊全的對象,因爲它是抽象的。

這種陰影真正發生在這裏:你不能通過值傳遞對象,並期望它們是多態的。如果你沒有看到這個錯誤,可能會發生的情況是你可能會調用slice your object,這可能更糟糕。做@billz建議並使用智能指針。

編輯:看到你添加你的insertEnd代碼,你在哪裏通過引用傳遞後,有一個附錄:編譯器要調用拷貝構造函數中insertEnd。相反,您可能會看到此行上的錯誤:newNode->item = new Item。在這裏你可以看到你試圖實例化抽象類的地方。將'Item'替換爲'vehicle' - 這就是您對模板所做的操作 - 並且您可以非常清楚地看到它。

在任何情況下,傳遞引用指針是一個非常痛苦和容易出錯的事情。這很容易引入錯誤:如果你的代碼中的任何地方都有delete v1,就像一個好的程序員所做的那樣(偉大的程序員使用自動指針),你可能會留下引用懸停:指向某個日子的內存空間 - 比如有人重要的是運行你的代碼 - 可能會充滿垃圾而不知道它的參考。這是瘋狂的方式,我的朋友。

這就是爲什麼智能指針是一個C++程序員最好的朋友:一旦你瞭解他們在做什麼,你都可以忽略,但這種混亂的,只是按值傳遞他們周圍自由。他們的生命週期契約是非常明確的,他們自己清理,他們是異常安全的。只要你沒有設置參考週期 - 這在日常使用中比傳遞一個取消引用的指針 - 或try to use auto_ptr in a standard container PLEASE READ THIS LINK AND UNDERSTAND IT的問題少得多,你已經大大減少了你的內存問題。

1

由於無法實例化抽象類型的對象,因此無法構造用於插入的對象。

另外,stl的複製構造語義不支持多態使用。 「車輛」列表應該只包含車輛物體,而不包含車輛物體。

你必須使用指針的容器。