C ++为什么默认副本不起作用?

时间:2017-03-09 23:00:22

标签: c++ copy-constructor

我做了很多谷歌搜索,似乎无法弄清楚发生了什么。我正在自学C ++(我对Java更熟悉)。

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

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

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

我想了解为什么这是必要的,以便将来能够认识到我在做什么。

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

通过将行更改为map.insert({key,value})来修复此问题

以下是两个类文件的重要部分:

//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 个答案:

答案 0 :(得分:0)

我认为问题出现了,因为您为item类声明了一个构造函数。 如果您不提供任何自定义构造函数,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

希望这能回答你的问题。