unique_ptr et polymorphisme
J'ai un code qui utilise actuellement les premières pointeurs, et je veux changer de pointeurs intelligents. Cela permet le nettoyage du code de diverses manières. De toute façon, j'ai de l'usine de méthodes qui retournent des objets et de son l'appelant de la responsabilité du gestionnaire. La propriété n'est pas partagé et donc je figure unique_ptr
serait approprié. Les objets de mon retour généralement tous dérivent d'une seule classe de base, Object
.
Par exemple,
class Object { ... };
class Number : public Object { ... };
class String : public Object { ... };
std::unique_ptr<Number> State::NewNumber(double value)
{
return std::unique_ptr<Number>(new Number(this, value));
}
std::unique_ptr<String> State::NewString(const char* value)
{
return std::unique_ptr<String>(new String(this, value));
}
Les objets retournés assez souvent d'avoir à passer à une autre fonction, qui opère sur des objets de type Object
(la classe de base). Sans pointeurs intelligents le code est comme ça.
void Push(const Object* object) { ... } //push simply pushes the value contained by object onto a stack, which makes a copy of the value
Number* number = NewNumber(5);
Push(number);
Lors de la conversion de ce code à utiliser unique_ptrs
j'ai rencontrer des problèmes avec le polymorphisme. Au départ, j'ai décidé de modifier la définition de Push
à utiliser unique_ptrs
trop, mais cela génère des erreurs de compilation lors de l'utilisation de types dérivés. J'ai pu allouer des objets que le type de base, comme
std::unique_ptr<Object> number = NewNumber(5);
et passer ceux Push
- qui, bien sûr, des œuvres. Cependant, j'ai souvent besoin d'appeler des méthodes sur le type dérivé. En fin de compte j'ai décidé de faire Push
fonctionner sur un pointeur vers l'objet stocké par le unique_ptr
.
void Push(const Object* object) { ... }
std::unique_ptr<Object> number = NewNumber(5);
Push(number.get());
Maintenant, la raison pour l'affichage. Je suis désireux de savoir si cela est normale pour résoudre le problème que j'ai eu? Est-il préférable d'avoir Push
fonctionner sur la unique_ptr
vs l'objet lui-même? Si oui, comment résoudre le polymorphisme des questions? Je suppose que, tout simplement, le casting du ptrs ne fonctionnerait pas. Est-il fréquent d'avoir besoin d'obtenir le sous-jacent à partir d'un pointeur de pointeur intelligent?
Merci, désolé si la question n'est pas claire (faites le moi savoir).
edit: je pense que ma fonction "Push" est un peu ambigu. Il fait une copie de la valeur sous-jacente et ne fait pas les modifier, ni de stocker, de l'objet d'entrée.
source d'informationauteur user1520427
Vous devez vous connecter pour publier un commentaire.
Il est probable que vous n'avez pas à traiter correctement avec l'unicité.
Si ce compilé, il serait trivialement briser l'invariant de
unique_ptr
qu'un seulunique_ptr
possède un objet, parce que les deuxi
et les locaux de l'argument danspush
serait propre qu'int
de sorte qu'il est illégal.unique_ptr
est déplacer uniquementil n'est pas copiable. Il n'a rien à voir avec les dérivés à base de conversion, quiunique_ptr
gère tout à fait correctement.Si
push
propriétaire de l'objet, puis utilisezstd::move
pour le déplacer. Si ça ne marche pas, puis d'utiliser un pointeur brut ou de référence, parce que c'est ce que vous utilisez pour les non-possesseurs d'un alias.Bien, si vos fonctions fonctionnent sur le (souligné) de l'objet lui-même et n'a pas besoin de son adresse, ni prendre aucun droit de propriété, et, comme je le suppose, a toujours besoin d'un objet valide (échec lorsqu'il est passé d'un
nullptr
), pourquoi prennent-ils des pointeurs?Le faire correctement et de leur faire prendre des références:
Puis le code d'appel est exactement le même pour les matières premières et les pointeurs intelligents:
EDIT: Mais bien sûr, peu importe si vous utilisez des références ou des pointeurs, ne font pas de
Push
prendre unstd::unique_ptr
si il ne prend pas la propriété de l'objet passé (ce qui en ferait voler la propriété du passé pointeur). Ou, en général, ne pas utiliser de posséder des pointeurs lorsque l'souligné l'objet est de ne pas être la propriété,std::shared_ptr
n'est pas quelque chose de différent à cet égard et il est pire qu'un choix comme unstd::unique_ptr
pourPush
's paramètre si il n'y a pas de droit de propriété devant être prises parPush
.Si
Push
ne pas prendre owenrship, il devrait probablement prendre de référence au lieu de pointeur. Et plus probablement unconst
. De sorte que vous aurezMaintenant, évidemment c'est seulement valable si le Pousser ne va pas garder le pointeur n'importe où passé, il est de retour. Si c'est le cas je soupçonne que vous devriez essayer de repenser la propriété première.
Voici un polymorphisme exemple d'utilisation de pointeur unique: