2010-01-05 6 views
2

depuis que je suis venu de C# à C++ tout semble fou pour moi en C++. Je me demandais si quelqu'un pouvait me expliquer pourquoi nous avons ce genre d'instancier en C++: Méthode 1:type différent d'instanciation sur C++

ClassA obj1; // this is going to stack 

Méthode 2:

ClassA *obj1 = new ClassA(); //this is going to heap 

alors que nous n'avons pas le instanciation commun en C# façon sur C++:

ClassA obj2 = new obj2(); 

et une autre question method1 je reçois une instance de la ClassA mais sans(), ce qui est le endroit exact, je suis confus, pourquoi devons-nous instater comme ça? notre ClassA a un constructeur mais instanciation sans parenthèses ??? comment se fait-il que nous appelons son constructeur?

p.s: J'ai lu ces sujets:

Different methods for instantiating an object in C++

Stack, Static, and Heap in C++

What and where are the stack and heap?

+0

C# n'a pas deux méthodes d'instanciation car le runtime gère la mémoire pour vous. –

+0

Dans la méthode 1, obj est une référence à un objet ClassA. Dans la méthode 2, obj est un pointeur vers un objet ClassA. new in C++ renvoie un pointeur vers la mémoire allouée. Vous devez dire à nouveau quel type d'objet créer. C'est en partie pourquoi la troisième option ne fonctionne pas. obj2 n'a pas été défini en tant qu'objet. À ce stade du code, il s'agit simplement d'un texte qui servira d'identifiant pour une référence à un objet une fois créé. – iheanyi

Répondre

3

mouvement en effet C++ à partir d'un langage comme Java ou C# peut être décourageant, je l'ai vécu aussi.

La première différence est qu'en C++ vous gérez presque toujours votre propre mémoire. Lorsque vous créez un objet sur le tas, vous devez le supprimer afin qu'il ne faille pas de mémoire. Cela signifie que vous pouvez le supprimer lorsque vous le souhaitez. Lorsque vous créez un objet sur la pile, il est automatiquement supprimé lorsqu'il est hors de portée - vous devez faire attention de ne pas l'utiliser après qu'il est hors de portée.

Exemple:

void do_queue(B& queue) 
{ 
    Evt *e = new Evt; 
    queue.queueEvent(e); 
} // all well, e can be popped and used (also must be deleted by someone else!) 

contre

void do_queue(B& queue) 
{ 
    Evt e; 
    queue.queueEvent(&e); 
} // e is out of scope here, popping it from the queue and using it will most likely cause a sigseg 

Cela dit, les deux méthodes sont également très différentes dans un aspect: le premier crée un objet. Le second crée un pointeur sur un objet. La bonne chose à propos des pointeurs est que vous pouvez les passer en paramètres avec seulement un minimum de mémoire étant copié sur la pile (le pointeur est copié, au lieu de l'objet entier). Bien sûr, vous pouvez toujours obtenir l'adresse d'un objet alloué sur la pile en utilisant "&", ou le passer comme référence. Cependant, lorsque vous utilisez des objets alloués sur la pile, vous devez faire particulièrement attention à leur portée.

J'ai trouvé ce site une grande ressource quand je suis passé de Java en C++: http://www.parashift.com/c++-faq-lite/ - vous probablement aussi, il offre beaucoup de bonnes explications

1

syntaxe C++ est comme ça. Si vous souhaitez utiliser le constructeur par défaut, vous appelez simplement comme ça:

ClassA obj1; 

Si vous avez un constructeur avec un paramètre, vous appelleriez comme ceci:

ClassA obj1(5); 
2

En C++, vous devez décider où vous voulez que votre objet résider. Par où je veux dire dans quel souvenir, la pile, ou le tas.

L'instanciation d'un objet est un processus en deux étapes. D'abord vous avez besoin de mémoire, et soit vous l'emportez sur la pile, soit vous l'allouez depuis le tas. Deuxièmement, vous initialisez la mémoire avec les valeurs souhaitées, c'est-à-dire que vous construisez l'objet en appelant sa fonction constructeur.

Ces deux syntaxes sont pour ces deux emplacements de mémoire différents possibles: la pile et le tas. En ce qui concerne la syntaxe et la parenthèse apparemment manquante pour l'objet alloué à la pile, il s'agit de désambiguïser entre la définition et la construction d'un objet, et la déclaration d'une fonction. En effet, ClassA obj(); déclare une fonction ne prenant aucun paramètre et renvoyant un objet ClassA.

Questions connexes