2010-08-10 14 views
1

Y at-il un moyen en C++ pour construire votre classe de telle sorte que, vu un pointeur sur votre classe, vous pouvez indiquer à dynamic_cast <>() comment transtyper dans une autre classe pour laquelle vous encapsulez l'implémentation? Est-ce que l'opérateur pourrait faire l'affaire? Imaginons que je possède une classe de base d'interface abstraite et que j'en dérive un concreteA ainsi que concreteB, mais concreteB enveloppe l'interface à un objet de type concreteA. Si je reçois une demande de jeter à concreteA de concreteA, je voudrais que cela fonctionne:Puis-je enseigner dynamic_cast <>() de nouveaux trucs?

class Abstract { 
public: 
    virtual void interface() = 0; 

}; 

class concreteA : public Abstract { 
public: 
    virtual void interface(); 

}; 

class concreteB : public Abstract { 
public: 
    concreteB(concreteA &underlying) 
    : _underlying(&underlying) { 
    } 
    virtual void interface(); 

    operator concreteA*() { 
    return _underlying; 
    } 

private: 
    concreteA *_underlying; 

}; 

void 
myTest() { 
    concreteA myClassA; 
    concreteB myClassB(myClassA); 
    Abstract *abstract = &myClassB; 
    concreteA *underlying = dynamic_cast<concreteA *>(abstract); 
} 

Répondre

4

n ° Un casting dynamique est dit au compilateur « Je ne veux pas changer cet objet du tout, je Je veux juste essayer de le regarder comme si c'était cet autre type, mais ne le changez pas Si vous devez le changer, renvoyez NULL ou lancez une exception. ". La distribution dynamique n'essaiera pas d'effectuer de telles conversions en votre nom. Pour cela, vous avez besoin de static_cast ou boost::lexical_cast.

En effet, l'opérateur coulé sous pression soit:

  • Réinterpréter un objet existant d'une manière nouvelle, sans changer
  • Modifier un objet d'une certaine façon afin de le contraindre à être un autre type, par exemple comme int -> short, ou double -> int.

et une seule invocation cast ne peut faire que un, pas les deux. Pour plus d'informations sur la nature «double» de l'opérateur de distribution, vous pouvez voir this article by Eric Lippert, qui est destiné à C# mais qui s'applique également à C++.

Plus précisément, vous pouvez voir le § 5.2.7 dans le plus récent projet C++ 0x - ce comportement n'est pas modifié à partir de C++ 03.