2013-01-22 2 views
3

몇 가지 간단한 클래스가있어서 작동시킬 수 없습니다.C++ OOP - 데이터 손실

TL; DR 인스턴스에 데이터를 설정 한 후 '플레이어'인스턴스가 있는데 다시 가져올 수 있습니다. 인스턴스를 std :: vector Players로 푸시하면; Players.at (0) .getName()이 있으면 ""을 반환합니다. 데이터가 없습니다! 사라. 주에

//Player.h 
#ifndef PLAYER_H 
#define PLAYER_H 

#include <iostream> 

class Player 
{ 
public: 
    Player(); 
    Player(const Player &Player); 
    Player& operator=(const Player &Player); 
    std::string getName(); 
    bool  setName(const std::string &name); 
    bool  nameValid(const std::string &name); 

private: 
    std::string _name; 
}; 



#endif 



//Player.cpp 

#include "Player.h" 
#include <iostream> 
#include <string> 
using namespace std; 

Player::Player() 
{ 

} 
Player::Player(const Player &Player) 
{ 

} 
Player& Player::operator=(const Player &Player) { 
    return *this; 
} 

std::string Player::getName() 
{ 
    return this->_name; 
} 

bool Player::setName(const std::string &name) 
{ 
    if (! this->nameValid(name)) 
    { 
     return false; 
    } 

    this->_name = name; 
    return true; 
} 

bool Player::nameValid(const std::string &name) 
{ 
    return name.empty() == false; 
} 




//Map.h 
#ifndef MAP_H 
#define MAP_H 

#define MAP_X 40 
#define MAP_Y 40 

#include "Player.h" 
#include "Point.h" 
#include <vector> 

class Map 
{ 
public: 
    Map(); 
    bool movePlayer(Player &Player, Point &Point); 
    std::vector<Player> getPlayers(); 
private: 

}; 

#endif //MAP_H 



//Map.cpp 

#include "Map.h" 
#include "Player.h" 
#include "Point.h" 
#include <iostream> 
#include <string> 

using namespace std; 

Map::Map() 
{ 

} 

bool Map::movePlayer(Player &Player, Point &Point) 
{ 
    return true; 
} 
std::vector<Player> Map::getPlayers() 
{ 
    Player vPlayer; 
    vPlayer.setName(std::string("test")); 
    std::vector<Player> Players; 

    Players.push_back(vPlayer); 

    return Players; 
} 

: 여기

(I는 = "" "_name"와 "VPLAYER"및 "플레이어"I가 요소 참조 설정 "_name"를 참조 어플리케이션 디버깅) 코드 인 :

std::vector<Player> Players = vMap.getPlayers(); 
    cout<<"Test:"<<Players.at(0).getName()<<endl; 
+2

복사, 이동 및 양도에 대한 정보는 http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom의 맨 위로 대답을 확인하십시오. – tecu

+1

'Players.push_back (vPlayer);를 호출 할 때 vPlayer의 현재 인스턴스를 벡터에 추가하지 않고 대신 벡터의 복사본을 추가합니다. 당신의 복사 생성자가 비어 있기 때문에 복사본의'_name' 필드도 비어 있습니다. –

+1

이 코드에서는'this->'몇 개를 잃을 수 있습니다. 필요하지 않으므로 (실제로는 C++에서는 드문 경우입니다). 예, 명시 적으로 암시 된 것보다 낫습니다. 그러나이 경우에는 코드가 "이상하게"만듭니다. – DevSolar

답변

4

벡터에는 벡터에 추가 한 요소의 사본이 포함됩니다. 이 복사본은 Player :: Player (const Player &) 생성자를 사용하여 추가됩니다.

이 생성자는 (구현시) 이름에 값을 설정하지 않습니다.

솔루션 :

  • 세트 복사 된 객체의 이름 :

    Player::Player(const Player &Player) : _name(Player._name) { }

(같은 당신의 할당 연산자 마찬가지입니다)

  • 제거 사본 및 부양 기본 기능에 의존합니다. 이름은 std :: string이므로 기본적으로 소스 플레이어 이름의 복사본을 가져옵니다.
+0

고맙습니다. @Angew 너무! – ioanb7

10

클래스의 복사 생성자 및 복사 할당 연산자를 정의하여 아무것도 수행하지 않습니다. 벡터의 복사본이 벡터에 넣은 인스턴스와 동일한 데이터를 가질 것이라고 어떻게 예상합니까?

클래스는 컴파일러에서 생성 한 기본 생성자 및 복사 할당 연산자로 완벽하게 문제가 없으므로 선언과 정의를 제거하면 모든 것이 작동합니다.