2009-09-02 6 views
0

J'essaie de faire un moteur de jeu simple. Je n'ai jamais utilisé de POO auparavant, donc c'est probablement une simple erreur, mais j'obtiens cette erreur en essayant de créer une instance d'une classe.Étrange problème avec les classes

invalid conversion from `World*' to `int' 
initializing argument 1 of `World::World(int)' 

Ceci est le code pour créer la classe.

World w = new World(100); 

Et la classe réelle:

class World { 
    int maxParts; 
    public: 
     GameObject **parts; 
     World(int maxParts); 
     int addObject(int type); 
    private: 
     int firstFreeId(); 
}; 

World::World(int maxParts) 
{ 
    parts = new GameObject *[maxParts]; 
} 

... 

Merci pour toute aide.

Répondre

7

L'opérateur new renvoie un pointeur:

World *w = new World(100); 

Après avoir créé un objet World de cette façon, vous accéder généralement à l'aide de l'opérateur ->:

w->addObject(5); 

Lorsque vous avez terminé avec elle, ne pas oublier à delete ou vous aurez une fuite de mémoire:

delete w; 
w = NULL; 

La définition de w = NULL n'est pas strictement nécessaire, mais c'est une bonne pratique car elle vous empêche d'accéder accidentellement à l'objet après sa suppression.

5

vous manque un astérisque ici:

World *w = new World(100); 

Lorsque vous créez quelque chose avec new il vous donne un pointeur vers le nouvel objet, donc la variable que vous placez le pointeur dans doit être déclaré par un astérisque.

+0

Merci, c'est exactement ce dont j'avais besoin. – phpscriptcoder

0

Je recommande fortement de commencer par C# ou Java au lieu de C++ pour apprendre la POO.

Puisqu'il a été reçu négativement j'ai édité la réponse. Je n'essayais pas d'être odieux. Ma recommandation se voici pourquoi:

Tout d'abord j'aime les raisons bien sûr de Dave Hinton (merci pour carillonner in), voici quelques-uns:

Je pense que si vous utilisez .net ou Java sdk vous aurez avoir beaucoup plus de bibliothèques de la boîte et objets à exploiter. Je sais que beaucoup existent en C++ mais sont un peu plus difficiles à acquérir et à assembler je pense. Je parle d'objets de niveau beaucoup plus élevé que le STL, bien sûr. Par exemple dans .net je peux utiliser quelque chose appelé un "MailMessage" pour construire un email. Je ne saurais pas comment faire ça ces jours-ci avec gcc et C++. Je suppose que l'accent est mis ici sur le support de framework pour Java ou C# par rapport à celui de C++ (non .net C++).

Ensuite, je pense que les espaces de noms sont légèrement plus facile en Java et C# bien que je sais que cela va probablement revenir en arrière.

Surtout, cela se résume au fait que si vous regardez les réponses proposées (et ils ont raison non?), Vous remarquerez qu'ils auraient jamais été un problème en Java ou C#:

  1. destructor
  2. astérisque manque
  3. confusion (pour les débutants, au moins était pour moi) entre '' et « -> »
+1

soin d'expliquer pourquoi? – markh44

+1

Les raisons possibles incluent: ne pas avoir à apprendre la gestion manuelle de la mémoire, ne pas avoir à se renseigner sur les pointeurs, ne pas avoir à s'inquiéter du préprocesseur. Bien que je suggère d'apprendre la POO en PHP, une langue que le PO est déjà familier, qui prend en charge OOP ces jours-ci. – dave4420

+1

C'est beaucoup mieux, downvote supprimé. Je suis d'accord que les choses que vous mentionnez pourraient être problématiques pour un débutant mais je ne suis pas d'accord que ces choses entraveraient de manière significative la compréhension de la POO. De plus, puisque la question mentionnait les jeux, peut-être que le PO a l'intention d'obtenir un emploi dans la programmation de jeux. Connaître le C++ est essentiel pour pratiquement n'importe quel travail de programmation de jeux que j'ai jamais vu. – markh44

13

new World(100) crée dynamiquement un nouvel objet World, passant de 100 au constructeur, mais évalue à un pointeur à l'objet créé.

Si vous voulez juste construire un objet World vous n'avez pas besoin d'une expression new, vous pouvez simplement construire directement:

World w(100); 

L'erreur que vous obtenez est parce que vous essayez de construire un World objet basé sur le pointeur World renvoyé par l'expression new. Le seul constructeur World prend un int et vous ne pouvez pas convertir un type de pointeur en int sans un cast explicite.

+0

Cela a créé l'objet, mais quand j'ai essayé d'utiliser une fonction de celui-ci j'ai eu une erreur que "w n'est pas une classe ou un objet." Je ne sais pas quel est le problème ... mais j'ai eu l'une des autres solutions affichées ici pour fonctionner. – phpscriptcoder

+2

Vous devez publier le code complet qui n'a pas fonctionné et le message d'erreur complet qu'il a généré, puis nous avons une chance de dire ce qui pourrait ne pas fonctionner. –

1

World w = foo; appelle le constructeur de World avec l'argument foo (sauf si foo est déjà un objet World), puis appelle le constructeur de copie de World avec le résultat comme argument. new World(foo) appelle le constructeur de World avec l'argument foo, stocke le résultat sur le tas et renvoie un pointeur sur celui-ci.

Alors World w = new World(100) crée d'abord un objet du monde sur le tas, appelant le constructeur avec le arguemnt 100. Il appelle alors le constructeur avec le résultat de new World(100) comme argument (parce que World w = foo appelle le constructeur avec foo comme argument) qui ne fonctionne pas car le constructeur n'accepte pas les arguments de type World*.

+1

Votre première déclaration est subtilement incorrecte. 'World w = foo' appelle le constructeur de' World' avec l'argument 'foo', créant ainsi un temporaire; puis, il appelle le constructeur de copie de 'World' pour instancier' w' lui-même par copie de ce temporaire. Le compilateur est autorisé à optimiser l'étape de copie, mais il doit signaler une erreur s'il n'y a pas de constructeur de copie accessible (même s'il ne l'utilise pas en raison de l'optimisation). Notez que VC++ n'est pas conforme à la norme à cet égard et ne vérifie pas l'accessibilité des constructeurs élidés. –

+0

"Le monde w = foo appelle le constructeur de World avec l'argument foo, créant ainsi un temporaire, puis il appelle le constructeur de copie de World pour instancier w lui-même par une copie de ce temporaire." Non, ça ne l'est pas. 'World w = foo' est le même que' World w (foo) '. Donc, à moins que foo ne soit réellement un objet World, aucun constructeur de copie n'est appelé. Vous pensez à 'World w = World (foo)' – sepp2k

+0

@ sepp2k: Pavel Minaev a raison, 'World w (foo)' est une * initialisation directe * et n'implique pas l'utilisation d'un constructeur de copie. 'World w = foo' est une * initialisation de la copie * et (logiquement) construit un 'World' temporaire à partir de' foo' et initalise 'w' du temporaire en utilisant le constructeur de la copie. Les deux expressions ont une sémantique identique uniquement lorsque 'foo' est un objet' World'. Le compilateur est autorisé à élider l'initialisation de copie * in * temporaire mais le constructeur de copie doit toujours être accessible et le constructeur utilisé (nominalement pour le temporaire) ne peut pas être explicite. Ce sont des différences importantes. –

3

Vous avez également besoin d'un destructeur pour nettoyer votre tableau de pointeurs.

World::~World() 
{ 
    delete[] parts; 
} 

Notez la forme différente de suppression lors de la suppression d'un tableau - c'est critique.

Ou vous pouvez utiliser std::vector<GameObject*> et vous n'aurez pas à vous en préoccuper.

+0

+1 pour mentionner 'std :: vector <>'. – dave4420