Comment convertir en classe dérivée? Les approches ci-dessous donnent toutes l'erreur suivante:
Impossible de convertir de BaseType en DerivedType. Aucun constructeur n'a pu prendre le type source, ou la résolution de surcharge du constructeur était ambiguë.
BaseType m_baseType;
DerivedType m_derivedType = m_baseType; // gives same error
DerivedType m_derivedType = (DerivedType)m_baseType; // gives same error
DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error
Pensez comme ceci:
class Animal { /* Some virtual members */ };
class Dog: public Animal {};
class Cat: public Animal {};
Dog dog;
Cat cat;
Animal& AnimalRef1 = dog; // Notice no cast required. (Dogs and cats are animals).
Animal& AnimalRef2 = cat;
Animal* AnimalPtr1 = &dog;
Animal* AnimlaPtr2 = &cat;
Cat& catRef1 = dynamic_cast<Cat&>(AnimalRef1); // Throws an exception AnimalRef1 is a dog
Cat* catPtr1 = dynamic_cast<Cat*>(AnimalPtr1); // Returns NULL AnimalPtr1 is a dog
Cat& catRef2 = dynamic_cast<Cat&>(AnimalRef2); // Works
Cat* catPtr2 = dynamic_cast<Cat*>(AnimalPtr2); // Works
// This on the other hand makes no sense
// An animal object is not a cat. Therefore it can not be treated like a Cat.
Animal a;
Cat& catRef1 = dynamic_cast<Cat&>(a); // Throws an exception Its not a CAT
Cat* catPtr1 = dynamic_cast<Cat*>(&a); // Returns NULL Its not a CAT.
Revenons maintenant à votre première déclaration:
Animal animal = cat; // This works. But it slices the cat part out and just
// assigns the animal part of the object.
Cat bigCat = animal; // Makes no sense.
// An animal is not a cat!!!!!
Dog bigDog = bigCat; // A cat is not a dog !!!!
Il est très rare que vous ayez besoin d'utiliser la distribution dynamique.
C'est pourquoi nous avons des méthodes virtuelles:
void makeNoise(Animal& animal)
{
animal.DoNoiseMake();
}
Dog dog;
Cat cat;
Duck duck;
Chicken chicken;
makeNoise(dog);
makeNoise(cat);
makeNoise(duck);
makeNoise(chicken);
La seule raison pour laquelle je peux penser est que si vous avez stocké votre objet dans un conteneur de classe de base:
std::vector<Animal*> barnYard;
barnYard.Push_back(&dog);
barnYard.Push_back(&cat);
barnYard.Push_back(&duck);
barnYard.Push_back(&chicken);
Dog* dog = dynamic_cast<Dog*>(barnYard[1]); // Note: NULL as this was the cat.
Mais si vous avez besoin de réinjecter des objets particuliers dans Dogs, il y a un problème fondamental dans votre conception. Vous devez accéder aux propriétés via les méthodes virtuelles.
barnYard[1]->DoNoiseMake();
dynamic_cast devrait être ce que vous recherchez.
MODIFIER:
DerivedType m_derivedType = m_baseType; // gives same error
Ce qui précède semble essayer d'appeler l'opérateur d'affectation, qui n'est probablement pas défini sur le type DerivedType et accepter un type de BaseType.
DerivedType * m_derivedType = (DerivedType*) & m_baseType; // gives same error
Vous êtes sur le bon chemin ici mais l'utilisation de dynamic_cast tentera de transtyper en toute sécurité vers le type fourni et s'il échoue, un NULL sera retourné.
En allant ici en mémoire, essayez ceci (mais notez que le cast retournera NULL pendant que vous castez d'un type de base vers un type dérivé):
DerivedType * m_derivedType = dynamic_cast<DerivedType*>(&m_baseType);
Si m_baseType était un pointeur et pointait réellement vers un type de DerivedType, alors dynamic_cast devrait fonctionner.
J'espère que cela t'aides!
Vous ne pouvez pas convertir un objet de base en un type dérivé - il n'est pas de ce type.
Si vous avez un pointeur de type de base vers un objet dérivé, vous pouvez le caster à l'aide de dynamic_cast. Par exemple:
DerivedType D;
BaseType B;
BaseType *B_ptr=&B
BaseType *D_ptr=&D;// get a base pointer to derived type
DerivedType *derived_ptr1=dynamic_cast<DerivedType*>(D_ptr);// works fine
DerivedType *derived_ptr2=dynamic_cast<DerivedType*>(B_ptr);// returns NULL
Tout d'abord - la condition préalable pour abattre est que l'objet que vous lancez est du type vers lequel vous lancez. La diffusion avec dynamic_cast vérifiera cette condition lors de l'exécution (à condition que l'objet converti ait certaines fonctions virtuelles) et lève bad_cast
Ou renvoie le pointeur NULL
en cas d'échec. Les conversions au moment de la compilation ne vérifieront rien et entraîneront simplement un comportement indéfini si cette condition préalable ne tient pas.
Analysons maintenant votre code:
DerivedType m_derivedType = m_baseType;
Ici, il n'y a pas de casting. Vous créez un nouvel objet de type DerivedType
et essayez de l'initialiser avec la valeur de la variable m_baseType.
La ligne suivante n'est pas beaucoup mieux:
DerivedType m_derivedType = (DerivedType)m_baseType;
Ici, vous créez un temporaire de type DerivedType
initialisé avec la valeur m_baseType
.
La dernière ligne
DerivedType * m_derivedType = (DerivedType*) & m_baseType;
devrait compiler à condition que BaseType
soit une classe de base publique directe ou indirecte de DerivedType
. Il a quand même deux défauts:
static_cast<DerivedType *>(&m_baseType)
BaseType m_baseType;
Donc toute utilisation du pointeur m_derivedType
Entraînera un comportement indéfini.