Question

  

Mise à jour 1:

     

Correction du code non-sens! Merci pour les commentaires, j'ai fait un hachage du premier extrait, oups.

     

Mise à jour 2:

     

Titre de la question également mis à jour, comme l'utilisation de dynamic_cast a été signalé comme non nécessaire réponses.

Ce que je suis en train de réaliser ici est une copie en profondeur en utilisant des types forts; Je veux être en mesure de copier Classe2 à une autre instance de classe 2; cependant, je veux aussi utiliser la fonction CopyTo de la classe 1 qui est la base. Cette idée vient de mon expérience C #, où habituellement je venais de faire le type de retour générique (voir extrait C #).

void Class1::CopyTo(Class1 *c1)
{
    // Write data in to c1 from this instance.
    c1->exampleData = exampleData;
}

// Class2 inherits Class1
Class2 *Class2::Copy()
{
    Class2 *c2a = new Class2();
    CopyTo(c2a);

    Class2 *c2b = dynamic_cast<Class2*>(c2a);
    return c2a;
}

Et voici la façon dont je l'avais donc en C #:

public class Class1
{
    T Copy<T>()
        where T : Class1
    {
        /* Can't remember the best way to do this in C#;
         * basically if T was Class2 this would need to create
         * a new instance of that class, and the same goes for
         * Class1. */         
        T copy = createNewInstance();

        // Copy the data from this to 'copy'.
        copy.exampleData = exampleData;

        return copy;
    }
}

Maintenant, par rapport à l'extrait de code C #, C ++ l'extrait se sentir nauséabond. Est-il possible de le faire sans pointeurs, ou est ainsi la meilleure pratique?

Était-ce utile?

La solution

Je ne sais pas ce que vous essayez d'atteindre parce que le code ne fonctionne toujours pas beaucoup de sens. Cependant, je crois que ce qui suit devrait se rapprocher de ce que vous essayez de faire. Notez que je ne pas utiliser la mémoire du tas. Il est pas nécessaire et il fuite de mémoire

template <typename T>
T Class1::Copy()
{
    T instance;
    CopyTo(&instance);
    return instance;
}

Cela fonctionne parce que vous passez un pointeur (polymorphes) à instance à la méthode CopyTo de Class1.

Ensuite, vous pouvez appeler le code comme ceci:

Class2 x1;
// Fill x1
Class2 x2 = x1.Copy<Class2>();

Cependant, ce code toujours sent parce qu'il n'y a pas idiomatiques C ++: En C ++, vous habituellement écrire un constructeur de copie à la place. méthodes de Copy liaison tardive existent, mais ils sont très rarement nécessaires, et ce qui précède ne sont pas en retard lié (mais ni est votre code C #).

Autres conseils

Je ne comprends pas ce que vous demandez, mais sachez que lorsque vous dites:

 Class2 *c2 = dynamic_cast<Class2*>(c1);

le résultat de la distribution pourrait être NULL et vous devez vérifier cela.

Vous devriez travailler sur l'extrait de code un peu plus. GetSomethingCopy crée un pointeur de type Classe2 qui est passé à CopyTo. CopyTo essaie d'appeler une fonction de membre du pointeur reçu qui n'a jamais été initialisé. Erreur de segmentation et le programme meurt

Même si cela ne tue pas l'application, vous essayez de dynamic_cast de Classe2 * à class2 * qui est à peu près rien faire. Si ce que vous avez l'intention est coulée la valeur retournée par CopyTo, vous devez savoir que vous ne pouvez pas utiliser dynamic_cast sur void *. Vous devez soit modifier la signature CopyTo pour revenir Class1 (de sorte que vous pouvez lancer plus tard) ou utiliser static_cast sur le vide *.

Notez que soit Copy est une fonction virtuelle dans Class1 qui est en fait exécuté en Classe2 et ne crée un objet Class2, ou bien, l'élément retourné ne sera pas un Classe2, mais plutôt un Class1.

Le nom de la méthode CopyTo est déroutante, car elle ne copie pas l'argument, mais plutôt de l'argument.

Et après tout cela, je sais toujours pas ce que vous demandez au sujet. Où voudriez-vous utiliser la mémoire de la pile? Vous pouvez passer un empilement élément affecté à une fonction, mais en renvoyant un pointeur / référence à un élément affecté de la pile est à nouveau une erreur de segmentation: l'objet sera détruit lorsque la fonction se termine et le récepteur sera laissé avec un pointeur / référence pendantes.

Maintenant, si votre question est plus théorique si vous pouvez utiliser dynamic_cast sur un élément de pile alloué, vous pouvez (à condition que Classe2 hérite de Class1):

void f()
{
   Class2 c2;
   Class1 &c1 = c2; // c1 is a Class1 reference to a Class2 object

   dynamic_cast<Class2&>(c1).class2method(); 
   // or:
   dynamic_cast<Class2*>(&c1)->class2method();
}

Si vous mettez à jour le code, poster un avis dans cette réponse pour que je remarque et peut corriger ce soir.

ce code n'a pas de sens comme il est dit ... de toute façon je « suppose » que vous pouvez utiliser si statique cast vous n'avez utilisé un vide * comme retour?

Ok maintenant le code est logique.

Vous ne avez pas besoin de casting dynamique, son déjà de type Classe2.

Dans votre fonction CopyTo, vous serait renvoyé un pointeur vers un objet qui a été créé sur la pile -. C'est impossible parce que l'objet les points de pointeur à sera détruit lorsque la fonction retourne

En réponse à votre question, vous pouvez utiliser dynamic_cast sur un pointeur ou une référence. Dans votre cas, je pourrais affecter l'objet à renvoyer dynamiquement à l'aide new plutôt que sur la pile, vous pouvez retourner en toute sécurité un pointeur. Cependant, je tendance à regarder sur l'utilisation dynamic_cast comme une odeur de code potentiel, et un signe qu'une fonction virtuelle doit être utilisée.

Non, dynamic_cast fonctionne uniquement avec des pointeurs et des références. Vous ne pouvez retourner tout ce que vous allouez sur la pile en toute sécurité de toute façon, donc je ne sais pas comment vous aviez l'intention de modifier votre code dans ce cas.

Ah, le problème est clair. La réponse est techniquement non, pas withh dynamic_cast <>, mais je suis vraiment ne pas voir pourquoi vous voulez de toute façon. Il semble que vous voulez juste

void Class1::CopyTo(Class1& c1)
{
    // Write data in to c1 from this instance.
    c1.SomeIntValue = SomeIntValue;
}

// Class2 inherits Class1
Class2* Class2::Copy()
{
    Class2 *c2 = new Class2();
    CopyTo(*c2);
    return c2;
}
//or more idiomatic
Class2 Class2::Copy()
{
    Class2 c2
    CopyTo(c2);
    return c2;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top