Question

J'ai déjà demandé pourquoi cela était considéré comme mauvais:

class Example
{
 public: 
  Example(void);
  ~Example(void);
  void f() {}
}

int main(void)
{
 Example ex(); // <<<<<< what is it called to call it like this?

 return(0);
}

Maintenant, je comprends que cela crée un prototype de fonction qui retourne un type Example. Je ne comprends toujours pas pourquoi cela fonctionnerait en g ++ et en MS VC ++.

Ma prochaine question utilise ce qui précède. Cet appel serait-il valide?

int main(void)
{
 Example *e = new Example();

 return(0);
}

? Quelle est la différence entre cela et simplement appeler Example e () ??? Par exemple, je sais que c'est un prototype de fonction, mais il semble que certains compilateurs pardonnent cela et lui permettent d'appeler le constructeur par défaut? J'ai aussi essayé ça:

class Example
{
 private:
  Example();

 public:
  ~Example();
};

int main(void)
{
 Example e1(); // this works
 Example *e1 = new Example(); // this doesn't

 return(0);
}

Je suis donc un peu confus :( Désolé si cela a été demandé un million de fois.

Était-ce utile?

La solution

cette question sera utile pour comprendre ce problème.

Autres conseils

C'est facile, Daniel:

Example *e = new Example();

Cela ne ressemble pas à une fonction appelée "Exemple", n'est-ce pas? Une fonction a une valeur de retour, un nom et des paramètres. Comment ce qui précède convient-il à cela?

  

Exemple e1 (); // ça marche

Oui, car vous ne créez aucune instance de Exemple nulle part. Vous indiquez simplement au code qu’une fonction est définie quelque part dans l’espace de noms environnant et que vous souhaitez éventuellement appeler cette fonction. Oui, il est vrai que pour renvoyer un objet de Example, une instance serait créée. Mais cela ne signifie pas qu'une instance est faite à ce stade. Au lieu de cela, une instance est créée dans la fonction, lorsque vous l'appelez.

Hmm ... OK ça:

Exemple e1 ();

Ne fonctionne pas. Vous le pensez peut-être, ou un compilateur l'accepte, mais il ne crée pas d'instance de Example appelée e1, il déclare simplement un prototype de fonction. Supprimez les crochets et faites ce que vous voulez.

Ceci:

Exemple * e1 = new Exemple ();

Ne fonctionnera pas car le constructeur est privé. Si vous rendez le constructeur public, il créera l'objet sur le tas et e1 sera un pointeur sur cet objet. Lorsque vous en aurez terminé, vous devrez supprimer l'objet.

Pour la première question de serait le "nouvel exemple ()" être valide. Oui, c'est du code C ++ parfaitement légal. Bien que pour être complètement correct, vous devrez supprimer l'objet avant de revenir de main (), sinon cela entraînerait une fuite de mémoire.

Exemple:

int main(void)
{
 Example *e = new Example();
 delete e;
 return(0);
}

Pour la dernière question. La ligne "Exemple e1 ();" est valide car il déclare un prototype de fonction. Cela n'entraîne pas l'exécution du code machine (peut-être que de la pile). Cela signifie simplement qu’il existe un prototype de fonction sans argument, renvoyant un type d’exemple.

La deuxième ligne échouera définitivement. A ce stade, vous essayez d'exécuter réellement le constructeur par exemple. Ce n’est pas légal car l’accessibilité de la fonction est privée, d’où l’erreur de compilation.

Je pense que vous devriez faire la différence entre 'this parses', 'this compile', 'this links' et 'this works', et essayez de penser vous-même comme un analyseur / compilateur / éditeur de liens C ++ pour voir que le premier exemple

Example e1(); // function prototype

ressemble à une déclaration de fonction. L’analyseur le comprendra ainsi, vous ne pourrez donc pas appeler, par exemple. une fonction membre sur e1 . Le compilateur générera un symbole faisant référence à une fonction (il ne le voit pas encore), mais comme la fonction n’est utilisée nulle part, elle ne se plaindra pas. Si vous ajoutez ce code, il sera:

e1.f();// since e1 is a function, it has no member 'f' => compiler error

(en tant que note de bas de page: ce code sera également compilé:

int a_function_prototype(int); // another prototype.
e1(); // should work!
a_function_prototype(5);

mais une fois le compilateur terminé, l'éditeur de liens commencera à rechercher les corps de fonctions réels et n'en trouvera aucun.)

Maintenant depuis la ligne

Example* e = new Example();

contient un mot clé new reconnu par le compilateur, et s'il sait qu'il ne peut être trouvé que dans allocation + construction d'un nouvel objet, il générera du code pour le faire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top