2017-03-09 3 views
-1

私は多くのGoogle検索を行っており、何が起こっているのかわからないようです。私は自分自身にC++を教えています(私はJavaにもっと精通しています)。C++なぜデフォルトのコピーは動作しませんでしたか?

ポインタとしてではなく、インベントリクラスマップに格納されているアイテムクラスオブジェクトがあります。私はインベントリから項目の1つを取り出し、インベントリマップから削除しながら一時変数に割り当ててから、オブジェクト自体を返して何か他のものが使用できるようにしたいと思います。私はもともと私の関数内のコードを使用してみましたときには(C++ライブラリのもののスタックトレースが続く)エラーを返していました:

no matching constructor for initialization of 'Item' 
      ::new ((void*)__p) _Tp(); 

私は、しかし、無駄に、コピーコンストラクタを作成してみました。最終的には、ヘッダファイルに空のコンストラクタ(Item();)を組み込み、それをcppファイル(Item :: Item(){})で定義することによって機能しました。

私はこれがなぜ必要なのか理解したいので、将来私が自分が何をしているのかを知ることができます。

EDIT:エラースタックトレースをさらに調べると、Inventory :: addItem関数で実際の問題が判明しました。演算子[]を使用してオブジェクトをマップに割り当てる場合、割り当てを行う前に、デフォルトのコンストラクタを使用して値の型をまずキーにインスタンス化します。デフォルトのコンストラクタは使用できなかったため、エラーが返されました。

それはmap.insertする行を変更することで修正されました({キー、値})ここで

は、2つのクラスファイルの重要な部分である:

//item.h 
#include <string> 
using namespace std; 

class Item { 
private: 
    string name; 
    int type; 
    int levelReq; 
public: 
    Item(string name, int type, int levelReq); 
    Item(); 
    string getName() {return name;} 
    int getType() {return type;} 
    friend ostream &operator<<(ostream &out, const Item &item); 
}; 
--------------------------------------------------------------- 
//item.cpp 
#include <string> 
#include "item.h" 

using namespace std; 
Item::Item(string n, int t, int l) : name(n), type(t), levelReq(l) {} 
Item::Item() {} 
ostream &operator<<(ostream &out, const Item &item) { 
    return out << item.name; 
} 
--------------------------------------------------------------- 
//inventory.h 
#include <map> 
#include "item.h" 

class Inventory { 
private: 
    map <int, Item> inventory; 
    int size; 
    bool full; 
    int nextFree; 
    void findNextFree(); 

public: 
    Inventory(); 
    bool isFull() {return full;} 
    void addItem(Item item); 
    Item getItem(int slot); 
    void showInv(); 
}; 
--------------------------------------------------------------- 
//inventory.cpp 
#include <iostream> 
#include <string> 
#include "inventory.h" 
#include "item.h" 

using namespace std; 

Inventory::Inventory() { 
    full = false; 
    nextFree = 1; 
    size = 28; 
} 

void Inventory::addItem(Item item) { 
    if (!full) { 
     inventory[nextFree] = item; 
     findNextFree(); 
    } 
    else { 
     cout << "Your inventory is full (Inv::addItem)"; 
    } 
} 

Item Inventory::getItem(int slot) { 
    Item item = inventory.at(slot); 
    inventory.erase(slot); 
    full = false; 

    if (nextFree > slot) { 
     nextFree = slot; 
    } 

    return item; 
}  

void Inventory::findNextFree() { 
    nextFree++; 

    if (nextFree == size + 1) { 
     full = true; 
    } 
    else if (inventory.count(nextFree)) { 
     findNextFree(); 
    } 
} 
+1

問題を示す最短**完全**プログラムにプログラムを縮小してください。役立つ情報については、[mcve]を参照してください。 –

+0

この回答を見てください:http://stackoverflow.com/a/695663/10077 –

+0

フィードバックいただきありがとうございます、私は私の次の投稿のために心に留めておきます。 –

答えて

0

私は思いますアイテムクラスのコンストラクタを宣言したために問題が発生しました。 カスタムコンストラクタを指定しない場合、C++は必要なコンストラクタを自動的に生成します。 必要なコンストラクタは、デフォルトのコピーコンストラクタと移動コンストラクタです。

デフォルトのコンストラクタは生成されず、この問題が発生します。この原則は構造体にも適用されます。

自分のために参照するための基準を確認します。 http://en.cppreference.com/w/cpp/language/default_constructor

http://en.cppreference.com/w/cpp/language/copy_constructor

http://en.cppreference.com/w/cpp/language/move_constructor

が、これは、あなたの質問に答える願っています。

関連する問題