2010-07-05 4 views
1

----- Bonjour, monde 2.cpp -----C++ problème CLI Classe

// Hello, World 2.cpp : main project file. 

#include "stdafx.h" 
#include "hello.h" 
#include <string> 

using namespace System; 
using namespace std; 

int main(array<System::String ^> ^args) 
{ 
    hello hi = new hello("Bob", "Blacksmith"); 
    Console::WriteLine(L"Hello, " + hi.getName + "!"); 
    return 0; 
} 

----- ----- hello.h

#include <string> 
using namespace std; 

#ifndef HELLO_H 
#define HELLO_H 

class hello 
{ 
private: 
    string _fname; 
    string _lname; 
    //hello() { } // private default constructor 

public: 
    hello(string fname, string lname); 
    void SetName(string fname, string lname); 
    string GetName(); 

}; 

#endif 

----- ----- bonjour.cpp

#include "stdafx.h" 
#include "hello.h" 
#include <string> 
using namespace std; 

hello::hello(string fname, string lname) 
{ 
    SetName(fname, lname); 
} 

void hello::SetName(string fname, string lname) 
{ 
    _fname = fname; 
    _lname = lname; 
} 

string hello::getName() 
{ 
    return _fname + _lname; 
} 

----- ----- Les erreurs

  • ------ Build a commencé: Projet: Bonjour, Monde 2, Configuration: Debug Win32 ------
  • Bonjour, 2.cpp Monde
  • Bonjour, 2.cpp Monde (12): erreur C2440: « initialisation »: ne peut pas convertir « bonjour * » pour « bonjour »
  • Aucun constructeur pourrait prendre le type de source, ou la résolution de surcharge du constructeur était ambigu
  • Bonjour, 2.cpp Monde (13): erreur C2039 : 'getName': n'est pas un membre de 'bonjour'
  • \ documents \ studio visuel 2010 \ projets \ cpp \ hello, monde 2 \ hello, monde 2 \ hello.h (8): voir la déclaration de 'bonjour'
  • hello.cpp
  • hello.cpp (17): erreur C2039: 'getName': n'est pas un membre de 'bonjour'
  • \ documents \ 2010 \ studio visuel projets \ cpp \ Bonjour, monde 2 \ bonjour, monde 2 \ hello.h (8): voir la déclaration de 'bonjour'
  • hello.cpp (19): erreur C2065: '_fname': identificateur non déclaré
  • hello.cpp (19): erreur C2065: « _lname ': identificateur non déclaré
  • Génération de code ... ========== Construire: 0 réussi, 1 a échoué, 0 mise à jour, 0 sautées ==========
+1

Ce n'est pas C++ - retagged. –

Répondre

3

Le mot-clé new crée un pointeur - si vous le faites de cette façon, « salut » devrait être déclarée comme hello*, ou vous devez reqrite la déclaration:

hello hi(...); 

La deuxième erreur est juste en raison de la casse (getName, GetName).

1
hello hi = new hello("William", "Dyson"); 

Doit être

hello* hi = new hello(...); 

Ou

hello hi("William", "Dyson"); ; 

Console::WriteLine(L"Hello, " + hi.getName + "!"); 

Doit être

Console::WriteLine(L"Hello, " + hi.getName() + "!"); 

Il peut y avoir d'autres échecs, mais je dois y aller maintenant.

+0

L "Bonjour,"? N'est-ce pas un littéral à chaîne large qui est implicitement converti en Char *, puis en System :: String? – Arafangion

5

Les messages d'erreur vous indiquent exactement où et quels sont les problèmes, bien qu'ils puissent être un peu intimidants au début. Peut-être que je peux aider à les démystifier un peu:

Bonjour, Monde 2.cpp (12): erreur C2440: « initialisation »: ne peut pas convertir « bonjour * » pour « bonjour »

Cela signifie que sur la ligne 12 Bonjour, 2.cpp monde, vous essayez de mettre un pointeur vers hello (le retour de new) à l'intérieur de hi qui n'est pas un type de pointeur. Puisque vous n'avez pas besoin d'un objet alloué dynamiquement ici, déposez simplement le new.

Dans les situations où vous avez besoin d'un objet alloué dynamiquement, vous devez remplacer la variable hi par hello * et ajouter un delete correspondant.

Bonjour, 2.cpp mondiale (13): erreur C2039: 'getName': ne fait pas partie de 'bonjour'

C++ est sensible à la casse. Dans un fichier vous avez GetName, dans l'autre vous avez getName. Choisissez-en un.

hello.cpp (19): erreur C2065: '_fname': identificateur non déclaré hello.cpp (19): erreur C2065: '_lname': identificateur non déclaré

ligne 19 de bonjour. cpp est la définition de la minuscule getName. Puisque getName n'a pas été déclaré dans la classe (voir l'erreur précédente), le compilateur n'a aucune idée de ce que sont _fname ou _lname. Ces erreurs disparaîtront une fois les problèmes d'origine résolus.

Modifier

la réponse Voir @ Sergey pour d'autres observations plus générales des choses à corriger.

0

Certains commentaires qui seront sans aucun doute être affiché avant que je fini d'écrire ceci:

  1. vous mettre les membres du public premier
  2. l'espace de noms System Managed C++ implique, si vous ne savez pas ce qui est et pense que vous utilisez C++ simple, s'il vous plaît lire à propos de printf et std::cout.
  3. La ligne

    hello hi = new hello("William", "Dyson");

    devrait lire

    hello hi("William", "Dyson"); ou hello* hi = new hello("William", "Dyson");

    Le premier crée un objet sur la pile (qui sera automatiquement détruit car il est hors de portée.Le second crée un pointeur vers un objet sur le tas, que vous devrez delete avant que le pointeur est hors de portée (après avoir fini avec elle)

  4. à propos hello::getName(): vous avez des fautes de frappe en ce qui concerne la capitalisation (gETNAME vs getName) et elle devrait être déclarée comme celui-ci (en-tête et par conséquent dans le fichier source):

    const string getName() const;

    la première const est facultative, mais je l'aime cette façon, le dernier vous permet d'appeler cette fonction d'un objet const hello et indique au lecteur que la fonction ne modifie pas l'objet.

  5. Vous devriez passer string par référence (ici est un constructeur de correcter):

    hello(const string &fname, const string& lname);

  6. Sources et les en-têtes doivent avoir un nom sans espaces (ou des caractères spéciaux) en eux, ce sera problématique pour UNIX < -> Windows si vous ne faites pas attention.

C'est tout ce que je peux voir maintenant.

+0

Les membres du public d'abord ou non est juste une question de goût. Et printf() n'est pas C++. – codymanix

+0

"Vous devriez passer une chaîne par référence": C'est un meilleur conseil si les chaînes ne sont pas copiées dans la fonction. Si vous envisagez de faire une copie, il est préférable de rendre la copie implicite (passer par la valeur) et laisser le compilateur déterminer la meilleure façon d'optimiser. – Cogwheel

+0

@codymanix: d'accord, mais beaucoup de gens l'utilisent. Je l'évite comme la peste. @ Cogwheel: d'accord, mais ça ne fait pas de mal de prendre l'habitude de passer autant que possible les références 'const'. – rubenvb

1

Il existe plusieurs erreurs.

  • Noms de fichiers avec des espaces. Pas critique, mais peut conduire à des problèmes
  • Console::WriteLine(L"Hello, " + hi.getName + "!");

cela devrait être quelque chose comme ceci:

string s("Hello, "); 
s += hi->getName(); 
s += "!" 
Console::WriteLine(s); 
  • supprimer les objets alloués avec le nouveau: delete hi;

  • string hello::getName() devrait être string hello::GetName()

  • Ne jamais utiliser le use namespace ... dans les fichiers d'en-tête

  • Inclure d'autres fichiers dans le bloc de garde

+0

+1 pour les deux derniers points – Cogwheel

0

Si vous allouez quelque chose avec new vous devez appeler delete après que vous n'avez plus besoin.

Si vous voulez utiliser le garbage collector le nettoyage pour vous que vous devez déclarer la classe comme ref class hello et instancier ensuite avec:

hello^ hi = gcnew hello(...);