2017-03-09 1 views
-1

나는 인터넷 검색을 많이 해왔고 무슨 일이 일어나고 있는지 파악하지 못했습니다. 나는 C++을 가르치고있다. (나는 자바에 대해 더 잘 알고있다.)C++ 기본 복사가 왜 작동하지 않았습니까?

포인터가 아니라 인벤토리 클래스 맵에 저장되는 항목 클래스 개체가 있습니다. 함수의 인벤토리에서 항목 중 하나를 검색하고 인벤토리 맵에서 해당 변수를 삭제하는 동안 임시 변수에 할당 한 다음 다른 사람이 사용할 수 있도록 객체 자체를 반환하려고합니다. 내가 원래 내 기능이 오류를 반환 한 내 코드를 사용했을 때 (C의 스택 추적 ++ 라이브러리 물건 뒤에) :

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

내가 복사 생성자를 생성했지만, 아무 소용. 결국, 그것은 내 헤더 파일에 빈 생성자 (Item();)를 포함하고 그것을 cpp 파일 (Item :: Item() {})에 정의함으로써 작동했습니다.

나는 왜 이것이 필요한지 이해하고 싶습니다. 그래서 앞으로 내가 무엇을하고 있는지 알게 될 것입니다.

EDIT : 오류 스택 추적을 추가로 검사하면 Inventory :: addItem 기능을 사용하여 실제 문제점이 밝혀졌습니다. 연산자 []를 사용하여 객체를지도에 할당 할 때지도는 할당하기 전에 기본 생성자를 사용하여 값 유형을 먼저 키로 인스턴스화합니다. 사용할 수있는 기본 생성자가 없으므로 오류가 반환되었습니다.

그것은 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

희망이 귀하의 질문에 대답을 제공합니다.

관련 문제