2017-03-09 68 views
-1

我做了很多谷歌搜索,似乎无法弄清楚发生了什么事情。我自学C++(我更熟悉Java)。C++为什么没有默认的副本工作?

我有存储在库存类映射中的Item类对象,而不是指针。我想从函数中的库存中检索其中一个项目,将其分配给一个临时变量,同时将其从库存地图中删除,然后返回对象本身,以便其他人可以使用它。当我用我的功能,它是返回错误中的代码最初试图(随后c的堆栈跟踪++库的东西):

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

我试图创建一个拷贝构造函数,但无济于事。最后,它通过在我的头文件中包含一个空构造函数(Item();)并在我的cpp文件(Item :: Item(){})中定义它。

我只想了解为什么这是必要的,所以我可以在将来知道我在做什么。

编辑:进一步检查错误堆栈跟踪后,它发现与Inventory :: addItem函数的实际问题。使用operator []将对象分配给映射时,映射首先使用默认构造函数将值类型实例化为键值,然后再进行赋值。没有默认的构造函数可用,所以返回错误。

它固定,通过改变线路map.insert({键,值})

下面是这两个类文件的重要组成部分:

//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

希望这回答了你的问题。

相关问题