6
votes

Appeler un constructeur pour réinitialiser les variables ne semble pas fonctionner?

Je voulais courir 1 000 itérations d'un programme, définissez donc un compteur pour 1000 sur la principale. J'avais besoin de réinitialiser diverses variables après chaque itération et que le constructeur de classe avait toutes les initialisations déjà écrites - j'ai décidé d'appeler cela après chaque itération, le résultat de chaque itération étant stockée dans une variable de la principale.

Cependant , quand j'ai appelé le constructeur, il n'avait aucun effet ... Cela m'a fallu un certain temps pour comprendre - mais cela n'a rien réinitialisé!

J'ai créé une fonction exactement comme le constructeur - l'objet aurait donc sa propre version. Quand j'ai appelé cela, il a tout réinitialisé comme on m'y attendait. xxx

... Est-ce que quelqu'un pourrait essayer d'expliquer pourquoi ce que je faisais était faux, ou n'a pas travaillé, ou n'était pas de travail ou idiot ou qu'avez-vous? Je veux dire - mentalement, je viens de figurer - merde, je peux appeler ce constructeur et avoir tout ce genre de choses réinitialisé. Sont des constructeurs (idéalement) uniquement appelés lorsqu'un objet est créé?


2 commentaires

Cela semble possible avec placement nouveau . Stackoverflow .com / questions / 6868363 / ...


myClass = classe (); ?


5 Réponses :


1
votes

Oui, cette utilisation n'est pas typique. Créez une fonction qui réinitialise vos variables et appelez la méthode à chaque fois que vous en avez besoin.


0 commentaires

0
votes

Vous avez chuté une proie à une mauvaise interprétation commune de C ++. Le nouveau C ++ 0x rend les choses un peu plus claires.

Le problème est que la syntaxe des constructions ressemble à un appel de fonction. P> xxx pré>

Je pense que la syntaxe C ++ 0x est plus clair. p>

Vous pouvez faire ce que vous voulez avec cette syntaxe. Mais méfiez-vous, il est très avancé et vous devriez pas strud> le faire. P>

MyClass.~Class(); // destruct MyClass
new( &MyClass ) Class;


1 commentaires

La principale raison pratique de ne pas le faire est que si le constructeur de classe , alors l'objet myClass est dans un état incohérent. La pile déroulant tentera de la détruire à nouveau, produisant un comportement indéfini. Cela, et cela ne vous gagne rien sur un opérateur bien écrit = ou réinitialiser la fonction membre (code> Membre. Donc, si vous contrôlez myClass , il n'est pas nécessaire de le faire, et si vous ne contrôlez pas myClass alors il demande des problèmes ;-)



5
votes

Que se passe-t-il dans cette ligne de lecture ...

Class ();


1 commentaires

"Je ne suis pas sûr de savoir si cela est autorisé ou non" - c'est, mais uniquement si ni le constructeur ni destructeur n'a aucun effet sur le comportement observable du programme. Donc, si vous avez mis des traces pour voir s'ils sont omis, ils ne peuvent pas être omis.



8
votes

Votre ligne classe (); code> appelle le constructeur de la classe classe code>, mais il l'appelle afin de créer un "objet temporaire". Puisque vous n'utilisez pas cet objet temporaire, la ligne n'a aucun effet utile.

Les objets temporaires (généralement) disparaissent à la fin de l'expression dans laquelle ils apparaissent. Ils sont utiles pour passer en tant que paramètres de fonction ou initialiser d'autres objets. Il n'est presque jamais utile de simplement en créer un dans une déclaration seule. La langue le permet comme une expression valide, c'est juste que pour la plupart des classes, il ne fait pas beaucoup. P>

Il n'y a aucun moyen en C ++ d'appeler un constructeur sur un objet qui a déjà été construit. Le cycle de vie d'un objet C ++ est une construction et une destruction. C'est à quoi ça marche. Si vous souhaitez réinitialiser un objet au cours de sa vie, vous avez fait la bonne chose, qui consiste à appeler une fonction pour le réinitialiser. Selon votre classe, vous n'avez peut-être pas besoin d'écrire un - l'opérateur d'affectation par défaut peut faire exactement ce dont vous avez besoin. C'est quand un temporaire peut être utile: p> xxx pré>

cette mise à jour myObject code> avec les valeurs de la construction temporaire fraîchement construite. Ce n'est pas nécessairement le code possible le plus efficace possible, car il crée une temporairement, puis des copies, puis détruit le temporaire, plutôt que de définir des champs à leurs valeurs initiales. Mais à moins que votre classe soit énorme, il est peu probable que tout ce que 1000 fois prendra une quantité de temps notable. P>

Une autre option est simplement d'utiliser un nouvel objet pour chaque itération: P>

int main() {
    int counter = 0;
    while (counter < 1000) {
        Class myObject;
        // stuff happens, each iteration has a brand new object
    }
}


3 commentaires

J'utilise des constructeurs, mais je passe rarement des paramètres, même si je sais que je peux. La plupart du temps, je me sens juste comme si je devrais les mettre à l'intérieur du constructeur du code source. Pourquoi passer des paramètres pour le faire via MAIN?


Dans ce cas, je suis très surpris que votre code compile, si vous n'utilisez pas de paramètres de constructeur, mais n'utilisez pas non plus la syntaxe correcte des constructeurs sans paramètre. Quoi qu'il en soit, la raison de l'utilisation des paramètres du constructeur est que si des objets de votre classe ne sont pas tous identiques. Jetez un coup d'œil à la bibliothèque standard pour des exemples - vous pouvez spécifier la taille initiale et le contenu d'un vecteur et ainsi de suite.


Utilisation de Microsoft Visual Studio C ++ et son compilateur intégré ... Si je déclare un constructeur comme KnightSTour :: KnightSTour (par exemple), puis mettez KnightSTour; Dans mon headerfile, il jette des erreurs, en disant que cela ressemble à une fonction, mais qu'il n'y a pas de paramètres. Soooo ... j'ai ajouté une liste de paramètres vide, c'est-à-dire "KnightSTour :: KnightSTour ()" Et puis "KnightStour ();" Dans la tête de tête - compile et fonctionne!



0
votes

Avec de telles exigences, j'écris généralement une méthode Clear () code> (public). Je l'appelle du constructeur, destructeurs. Le code d'utilisateur peut l'appeler chaque fois qu'il le souhaite.

class Foo
{
  public:

    Foo() { clear(); }

    ~Foo() { clear(); }

    void clear(); // (re)initialize the private members

  private:

     // private members
 };


0 commentaires