2010-06-03 7 views
1

Disons que je souhaite que mes utilisateurs utilisent une seule classe, par exemple SpecialData. Maintenant, cette classe de données aurait de nombreuses méthodes, et selon le type de données, les méthodes font des choses différentes, en interne, mais retournent des résultats similaires à l'extérieur. Par conséquent, mon souhait d'avoir une classe "publique" et d'autres "privées", des classes enfants qui changeraient le comportement des méthodes, etc ...Créer une instance à partir d'une méthode statique

Il serait étonnamment plus simple pour certains types de données qui doivent être construits de faire quelque chose comme ceci:

SpecialData& sm = SpecialData::new_supermatrix(); 

et new_supermatrix() retournera une instance SuperMatrix, qui hérite de la plupart des comportements de SpecialData.

mon en-tête:

static SpecialData& new_supermatrix(); 

mon cpp:

SpecialData& SpecialData::new_supermatrix()(){ 
    return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
} 

Le problème est, je reçois cette erreur, ce qui est probablement logique en raison des circonstances:

initialisation invalide de référence non-const du type 'SpecialData &' à partir d'un temporaire de type 'SpecialData'

Alors, des idées?

+0

Vous devez apprendre comment fonctionne une pile. –

+0

en effet, merci à tous pour les réponses. Je pense que je vais rester avec un espace de noms d'usine. – Manux

Répondre

3

Eh bien, vous avez trois choix:

a) Vous voulez avoir une seule instance de SuperMatrix de toute façon. Ensuite, optez pour l'itinéraire de la fonction statique, comme cela a déjà été suggéré.

b) Vous souhaitez créer plusieurs instances. Ensuite, vous avez de retourner un pointeur au lieu de références et de créer les objets avec de nouveaux (c.-à-return new SuperMatrix(...).

c) Comme alternative à l'option b, vous pouvez également revenir simplement un objet, par exemple

SpecialData SpecialData::new_supermatrix()(){ 
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
} 

Cependant, cela nécessite un opérateur de copie (profonde) (celui par défaut ne suffira pas le plus souvent), et cela signifie que l'objet est créé sur la pile, puis copié et que cette copie est retournée. La bonne chose est, cela ne fuira pas la mémoire si vous ne recevez pas réellement le résultat dans une variable. La mauvaise chose est, si l'objet est très grand, cela peut prendre beaucoup de mémoire et de temps. Peu importe ce que vous allez en faire, ces solutions sont mutuellement exclusives, à la fois techniquement et logiquement. ;)

0

Vous devez utiliser l'opérateur new. La création que vous obtenez par return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); alloue l'objet sur la pile, qui est nettoyé lorsque la fonction retourne (ce qu'elle fait dans la même ligne). L'utilisation de new provoque son allocation sur le tas.

2

Réponse simple - vous ne pouvez pas utiliser de références de ce type. Votre fonction new_supermatrix renvoie une valeur temporaire sans nom que vous essayez de lier à une référence non-const - C++ autorise uniquement ces valeurs à être liées à des références const. Si vous voulez écrire des fonctions comme celle-ci, vous devez les faire retourner un pointeur vers un objet alloué dynamiquement, ou coller avec le retour d'une valeur, mais affecter la valeur de retour à une autre valeur dans le code appelant.

1

Ce code présente plusieurs problèmes. Tout d'abord, vous voulez probablement utiliser des pointeurs ici au lieu de références. Renvoyer une référence à un objet créé sur la pile comme vous le faites dans votre new_supermatrix conduira à un crash presque immédiatement. Il doit être alloué avec new et renvoyé comme un pointeur si c'est ce que vous voulez mais je ne suis pas exactement sûr de ce que vous essayez de faire. Mais de toute façon, c'est ce qui cause votre erreur, vous renvoyez une référence à une variable temporaire.

0

Dans votre méthode, vous pouvez utiliser un static:

SpecialData& SpecialData::new_supermatrix()(){ 
    static SuperMatrix supermatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
    return supermatrix; 
} 
0

Vous ne devez pas renvoyer une référence à un objet temporaire/local.

Ceci et beaucoup d'autres erreurs courantes à éviter sont expliquées dans le livre de Meyers, Effective C++.

0

Vous renvoyez une référence à un objet temporaire, ce qui est une mauvaise nouvelle, car une fois que la méthode est terminée, l'objet n'existe plus.

Lire sur creational design patterns. Celui qui ressemble le plus à ce que vous voulez faire est le modèle Factory Method.

Questions connexes