Question

J'ai une classe de base et une classe dérivée. Chaque classe a un fichier .h et un fichier .cpp.

Je fais dynamic_cast de l'objet de classe de base à la classe dérivée dans le code suivant:

Les fichiers h:

class Base
{
  public:
    Base();
    virtual ~Base();
};

class Derived : public Base
{
  public:
    Derived(){};
    void foo();
};

class Another
{
  public:
    Another(){};
    void bar(Base* pointerToBaseObject);
};

Les fichiers cpp:

Base::Base()
{
    //do something....
}
Base::~Base()
{
    //do something....
}
void Derived::foo()
{
    Another a;
    a.bar(this);
}
void Another::bar(Base* pointerToBaseObject)
{
    dynamic_cast<Derived*>(pointerToBaseObject)
}

De quelque étrange raison, la coulée échoue (renvoie NULL). Cependant, la coulée réussit si je déplace la mise en œuvre du constructeur de classe dérivée de .h au fichier .cpp.

Que peut-il faire?

Le compilateur gcc 3.1, sous Linux SUSE. BTW, je vois ce comportement que sur cette plate-forme et le même code fonctionne très bien dans Visual Studio.

Était-ce utile?

La solution

Le code, comme affiché, ne devrait pas manquer, à condition que vous avez une fonction virtuelle dans la classe de base (comme litb souligné).

Mais je crois que chaque compilateur courant génère une « classe de base n'est pas polymorphes » genre d'erreur si vous ne l'aviez pas, de sorte que ne sera probablement pas le problème.

La seule chose que je peux penser est que à cause d'un bug tout bizarre s'inline et ne vtable est généré. Mais si vous mettez le constructeur dans le fichier C de, le compilateur décide de ne pas inline tout, ce qui déclenche la création d'un vtable, provoquant votre casting de travailler.

Mais cela est très sauvage devinettes, et je ne pense pas que tout compilateur aurait une telle erreur en elle (?)

Si vous voulez une réponse définitive, poster plus de code. Et le compilateur / plate-forme utilisée.

EDIT: En voyant le code mis à jour

Je pense que vous devriez au moins Dérive Dérivé de base;) (je suppose que c'est une faute de frappe)

Mais après avoir vu le code, la seule chose que je peux penser est que gcc (à tort) inline tout et ne génère pas de vtable pour dérivé. Pour ce que ça vaut la peine, cela va bien compilé avec gcc 4.0

3.1 est vieux maintenant plus de 7 ans ... s'il y a une possibilité de mettre à jour je vais pour cela.

Autres conseils

Avez-vous une fonction virtuelle dans la base? Il ne fonctionnera pas autrement. Si rien d'autre, faire son dtor virtuel.

Je ne sais pas si elle a déjà été posée par l'autre gars qui a supprimé sa réponse, mais je crois qu'il était quelque chose de différent: Vous faites le dynamic_cast du constructeur des bases? Si oui, cela ne fonctionnera pas. Le compilateur pense que la base est le type le plus dérivé, comme lorsque vous appelez une fonction virtuelle et il finit par appeler la version de la base.

Faire le destructeur virtuel, et placez-le (ou au moins une méthode virtuelle) dans le fichier cpp.

Certains compilateurs (lire: gcc) recherchent la première rencontre corps de méthode virtuelle non-ligne et l'utiliser pour décider où mettre la table de méthode virtuelle. Si vous ne disposez pas des méthodes virtuelles avec des organismes dans un fichier cpp, la table de méthode virtuelle n'est pas créé.

Vous devez avoir au moins une méthode virtuelle pour dynamic_cast travailler. Dynamic cast utilise la table pour trouver des informations de type, et aucune table est créée s'il n'y a pas des méthodes virtuelles.

Si vous avez une classe que vous vous attendez à être sous-classé et il a une destructor ou si la classe a des variables d'instance qui sont des classes avec Destructeurs, alors vous voulez vraiment faire de votre destructor virtuel (même si elle a une corps vide). Sinon, le nettoyage que vous attendez ne se produira pas pour les cas de sous-classe.

Ce que tu fais dans Visual C ++? Je pense que vous utiliser pour avoir des informations pour permettre de type d'exécution (RTTI) dans le cadre du compilateur pour que cela fonctionne.

S'il vous plaît ne me flamme pas si je l'ai eu ce tort. Cela a été un moment que je C ++ !!!

En regardant votre code, je ne vois pas d'héritage. Vous avez oublié de le faire? DERIVE ne dérive pas de quoi que ce soit.

Dans le code que vous avez posté dérivé ne provient pas de la base.

Modifier Pour votre information, le code modifié fonctionne très bien avec g ++ 3.4.5

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top