0

オブジェクトやオブジェクトへのポインターなど、さまざまな種類のデータを操作する汎用リンク リストがありますが、抽象クラスから派生したクラスからオブジェクトを挿入すると、リストの操作に問題が発生します。

vehicle という抽象クラスと、carr と truck の 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);

エラーがあります:

抽象型「車両」のオブジェクトを割り当てることができません

そして、コンパイラは、リンク リスト コードの insertEnd メソッドの次の記述部分にエラーがあることを示しています。

newNode->item = new Item;

これは、車両のリストが必要なプロジェクトの一部であり、車両は車、トラックなどにすることができます。ポインターへのポインターを使用して実装された車両のグループがありますが、車両のリストでこれを実行しようとしています.

手伝って頂けますか?

編集: アイテムはリンクされたリストにあります。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++;
    }
}
4

3 に答える 3

5

You are trying to store an item by value in your linked list. Using items by value breaks polymorphism: only pointers or references are polymorphic.

The reason this is the error you see is that you are dereferencing your pointer here: lv.insertEnd(*v1). Passing in a value this way will cause C++ to use the copy constructor for the type specified in insertEnd to make the object inside of your insertEnd function (check your code: the type of the parameter to insertEnd is surely the type specified in your template - which is vehicle here). By passing by value, you are telling your code to copy the whole of v1 into a new object inside of insertEnd. This falls apart, because vehicle is an abstract class: its copy constructor cannot be used to make a fully functional object, because it's abstract.

This sort of shadows what's really going on here: you can't pass around objects by value and expect them to be polymorphic. If you don't see this error, what will likely happen is that you will likely slice your object, which can be even worse to debug. Do what @billz recommends and use a smart pointer.

EDIT: after seeing your addition of your insertEnd code, where you are passing by reference, there is an addendum: the compiler is not going to call the copy constructor in insertEnd. Instead, you likely see the error on this line: newNode->item = new Item. Here you can see where you are trying to instantiate the abstract class. Replace the word 'Item' with 'vehicle' - that's what you're doing with your template - and you can see it very clearly.

In any case, passing-by-reference to a dereferenced pointer is a very painful and error-prone thing indeed. It's way too easy to introduce errors: if you delete v1 anywhere in your code, like a good programmer does (great ones use auto pointers), you are likely to leave your reference dangling: pointing to a space in memory that someday - like when someone important is running your code - may be filled with garbage without your reference knowing it. This be the way to madness, my friend.

This is exactly why smart pointers are a C++ programmer's best friend: once you understand what they're doing, you can all but ignore this sort of mess and just pass them around by value freely. Their lifecycle contract is very well defined, they clean up after themselves, they are exception safe. As long as you don't set up reference cycles - which is far less problematic in everyday usage than passing a dereferenced pointer by reference - or try to use auto_ptr in a standard container PLEASE READ THIS LINK AND UNDERSTAND IT, you've vastly reduced your memory problems.

于 2013-01-07T01:47:11.253 に答える
2

you need to use pointer in this case, the better way is to use smart pointer.

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

In your list<vehicle> lv;, lv only contains vehicle type object, lv.insertEnd(*v1); will slice your object to vehicle type which is not allow as vehicle is abstract class.

于 2013-01-07T01:47:07.930 に答える
1

抽象型のオブジェクトをインスタンス化できないため、挿入するオブジェクトを構築できませんでした。

また、stl のコピー構築セマンティクスは多態的な使用をサポートしていません。「車両」リストには、車のオブジェクトではなく、車両のオブジェクトのみを含める必要があります。

ポインターのコンテナーを使用する必要があります。

于 2013-01-07T01:50:08.347 に答える