Problème avec mon vector

Résolu
cs_Hades5k Messages postés 12 Date d'inscription mercredi 10 juillet 2002 Statut Membre Dernière intervention 1 décembre 2005 - 17 nov. 2005 à 06:04
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 - 22 nov. 2005 à 10:55
Bonjour!
J'apprends le C++ en essayant de faire un petit jeu dans la console. J'utilise un vector pour faire office d'inventaire dans lequel je pousse des objets de type CComponent.

Pour générer un inventaire temporaire, j'utilise une boucle pour ajouter 10 CComponent ... et ça plante quelque chose de rare!

Tout est dans le rar avec un screenshot...

Merci!

6 réponses

cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
17 nov. 2005 à 14:02
salut,

ton probleme vient de cet endroit:

// loop to generate temporary "inventory"

for(int i = 0; i < 10; i++)

{

CComponent c("Component#" + i);



l'addition que tu fais est en faite considérée comme une addition entre
un pointeur et un entier (car "Component#" est de type char*).

"Component#" + i est equivalent à &"Component#"[i], c'est a dire l'adresse du début de la chaine "Component#" plus i.



ceci explique que ta ligne se racourcissait, car le nom passé a ton
constructeur est un string lui meme construit a partir du char* la,
dont l'adresse avancait.



toi ce que tu voulais faire est une concaténation...

voila comment faire:



#include <sstream>



// fonction qui convertit n'importe quoi en un string.

template <typename T> std::string toString(T i)

{

std::stringstream ss;

ss << i;

return ss.str();

}

// specialisation pour le type int sous windows

template <>

std::string toString(int i)

{

char buffer[100];

itoa(i, buffer, 10);

return string(buffer);

}





// loop to generate temporary "inventory"

for(int i = 0; i < 10; i++)

{

CComponent c("Component#" + toString(i));



et voila...



a+
3
cs_Hades5k Messages postés 12 Date d'inscription mercredi 10 juillet 2002 Statut Membre Dernière intervention 1 décembre 2005
17 nov. 2005 à 06:18
Euh ok... désolé, j'ai pas mis de rar... j'ai pas trouvé comment... je paste le contenu du code ...

// MAIN.CPP

#include <string>
#include
#include "CComponent.h"
#include "CPlayer.h"


using namespace std;



int main()
{
cout << "Part 1 ------------------" << endl;


CComponent c;
c.use();
c.drop();


cout << "\nEnd Part 1...\n\n";


cout << "Part 2 ------------------" << endl;


CComponent c2("Sulfur");
c2.use();
c2.drop();


cout << "\nEnd Part 2...\n\n";


CComponent c3("Blue Meteor", 300, 2, POINT2D(3,4));
c3.use();
c3.drop();

cout << "\nFini #2...\n\n";


cout << "******************************************\n\n";
CPlayer *player = new CPlayer("Chris", BLUEMAGE, ELF, 560);
player->listInventory();
cout << "******************************************\n\n";


return 0;
}

// FULLINCLUDE.H

struct POINT2D
{
POINT2D() : width(0), height(0) {};
POINT2D(int x, int y) : width(x), height(y) {};
int width;
int height;
};


enum MageType { BLUEMAGE, REDMAGE, GREENMAGE, WHITEMAGE, BLACKMAGE };
enum RaceType { HUMAN, HALFELF, ELF, DARKELF, HALFDARKELF, ORC };

// CITEM.H

#ifndef _CITEM_
#define _CITEM_


#include <string>
#include "FullInclude.h"


using namespace std;


class CItem
{

public:
virtual bool use(void) = 0;
virtual bool drop(void) = 0;
};


#endif

// CCOMPONENT.H

#ifndef _CCOMPONENT_
#define _CCOMPONENT_


#include <string>
#include "CItem.h"


using namespace std;


class CComponent : public CItem
{
private:
string name;
int weight;
long value;
POINT2D size;


static int nbItem;


public:
CComponent();
CComponent(string pName);
CComponent(string pName, int pValue, int pWeight, POINT2D pSize);


~CComponent();


bool use(void);
bool drop(void);
void reveal(void);
};


#endif

// CPLAYER.H

#ifndef _CPLAYER_
#define _CPLAYER_


#include <string>
#include <vector>
#include "CComponent.h"


using namespace std;


class CPlayer
{
private:
string name;
MageType magetype;
RaceType racetype;
long kyna;
vector<CComponent> inventory;


public:
CPlayer();
CPlayer(string pName, MageType pMagetype, RaceType pRacetype, long pKyna);
~CPlayer();


void listInventory(void);
//void useItem(CItem &item);
};


#endif

// CCOMPONENT.CPP

#include <string>
#include
#include "CComponent.h"


using namespace std;


int CComponent::nbItem = 0;


// Default constructor
CComponent::CComponent() {


cout << "CComponent created...\n";
CComponent::nbItem++;
cout << "nbItem : " << CComponent::nbItem << endl;
}


// Constructor which names the component
CComponent::CComponent(string pName) {


name = pName;
cout << "CComponent created (" << name << ")...\n";
CComponent::nbItem++;
cout << "nbItem : " << CComponent::nbItem << endl;
}


// Full constructor
CComponent::CComponent(string pName, int pValue, int pWeight, POINT2D pSize) {


name = pName;
value = pValue;
weight = pWeight;
size = pSize;
cout << "CComponent created (" << name << ", " << value << ", " << weight << ", W:" << size.width << ", H" << size.height << ")...\n";
CComponent::nbItem++;
cout << "nbItem : " << CComponent::nbItem << endl;
}


// Destructor
CComponent::~CComponent()
{


CComponent::nbItem--;


}


// This function is called whenever the player wants to use a component
bool CComponent::use(void)
{
cout << "Component used...\n";


return true;
}


// When the component is dropped
bool CComponent::drop(void)
{
cout << "Component dropped...\n";


return true;
}


void CComponent::reveal(void)
{
cout << name;
}

// CPLAYER.CPP

#include <string>
#include
#include "CPlayer.h"


using namespace std;


CPlayer::CPlayer()
{
name = "Default Player Name";
magetype = BLUEMAGE;
racetype = HUMAN;
kyna = 0;
}


CPlayer::CPlayer(string pName, MageType pMagetype, RaceType pRacetype, long pKyna)
{
name = pName;
magetype = pMagetype;
racetype = pRacetype;
kyna = pKyna;


// loop to generate temporary "inventory"
for(int i = 0; i < 10; i++)
{
CComponent c("Component#" + i);
inventory.push_back(c);
}
}


CPlayer::~CPlayer()
{
cout << "I am destroyed...\n";
}


void CPlayer::listInventory(void)
{
vector<CComponent>::iterator iter;


for(iter = inventory.begin(); iter != inventory.end(); iter++)
{
CComponent tmpC = *(iter);
tmpC.reveal();
}
}

Quand le CComponent est crée... il affiche son nom... et celui-ci est toujours tronqué de plus en plus...
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
17 nov. 2005 à 14:15
de plus, tu peux constater que ton compteur d'items foire.

c'est parce que tu n'as pas défini de constructeur de copie pour ta
classe CComponent : et que qd tu écris CComponent tmpC = *(iter); le
compilateur t'en fait un automatique.

aucun de tes constructeurs classiques n'est appelé, et donc la variable static nbitem n'est a ce moment pas incrémentée.

par contre ton objet local sera détruit, et nbitem sera décrémenté : ceci explique pourquoi tu as un nombre d'item négatifs.



constructeur de copie :

CComponent::CComponent(const CComponent& b)

{

name = b.name;

weight = b.weight ;

value = b.value ;

size = b.size;

CComponent::nbItem++;

}



en C++, pour éviter des problemes (notamment fuite de mémoire, et
d'autres); chaque classe doit posseder un constructeur de copie , et un
opérateur d'affectation. (CComponent& operator = (const
CComponent& b) { ... ; return *this ; } )



si tu ne veux pas les implémenter, tu les mets en private: le
compilateur te signalera ainsi une erreur si tu essaies de copier un
tel objet. mais au moins il ne generera pas tout seul de constructeur
de copie par défaut, ou d'operateur d'affectation par défaut, qui
peuvent causer des problemes pour les classes non triviales.



a+
0
cs_Hades5k Messages postés 12 Date d'inscription mercredi 10 juillet 2002 Statut Membre Dernière intervention 1 décembre 2005
17 nov. 2005 à 20:13
cosmobob... merci!
je pouvais pas demander mieux

je vais arranger mon code maintenant!

merci encore!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Hades5k Messages postés 12 Date d'inscription mercredi 10 juillet 2002 Statut Membre Dernière intervention 1 décembre 2005
19 nov. 2005 à 02:39
J'ai essayé de créer le copy constructor... mais le compilateur me renvoit l'erreur suivante :

C:\Documents and Settings\DarkHades\Bureau\C++\SpellV1\SpellV1\CComponent.cpp(39) : error C2084: function '__thiscall CComponent::CComponent(const class CComponent &)' already has a body
0
cosmobob Messages postés 700 Date d'inscription mardi 30 décembre 2003 Statut Membre Dernière intervention 27 janvier 2009 4
22 nov. 2005 à 10:55
ben s'il a deja un corps, c'est que t'as du tout mettre ds le .h. Pour eviter ca, ne mets que la déclaration ds le header:

class CComponent

{

..

public:

CComponent(const CComponent& b);

};



et ds le .cpp:

CComponent::CComponent(const CComponent& b)

{

// ce qu'il faut

}

a+
0
Rejoignez-nous