2010-10-10 14 views
0
class B{ 
    private: 
    int a; 
} 
class D: public B{ 
    private: 
    int b; 
} 

B* b = new B; 

Maintenant, pour une raison quelconque, je veux tourbdans un D* type d'objet. par exemple. conserver les informations de B et deviennent D avec des informations supplémentaires requises.upcast à l'exécution. (Morphing classe de base pour dériver la classe)

Ce à quoi je pense actuellement est. static_cast pour faire le upcasting. les attributs supplémentaires seront définis sur null ou garbage. puis affectez les attributs supplémentaires manuellement. Mais cela conduit à un risque de pointeur pendante. Si le constructeur de copie n'est pas codé avec suffisamment de soin.

Alors quoi d'autre pourrait être la bonne solution?
et y at-il une solution du Puzzle si nous le pensons d'un point de vue PHP?

+0

Pourquoi voulez-vous faire cela? Il y a probablement une meilleure solution que de convertir un non-'D' en un' D' en castant. –

Répondre

0

Si vous faites un static_cast<> alors les attributs supplémentaires seront ne nul ou d'ordures, ils seront effectivement en dehors la mémoire allouée pour l'objet. Utilisez dynamic_cast<>, qui échouera correctement si la variable ne contient pas le bon type.

En outre, la similarité entre C++ et PHP dans ce cas est simplement superficielle; ne l'utilisez pas pour mieux comprendre le code C++.

+0

Désolé, je ne pouvais pas comprendre ce que vous vouliez dire par imploser. est-ce que 'dynamic_cast <>' rendrait des propriétés supplémentaires nulles ou non? par exemple. allouer de la mémoire pour cela? –

+0

Ya je sais Mais je dois faire l'architecture de telle sorte que je fonctionne à la fois comme CGI sur C++ ainsi que sur PHP –

+0

Si utilisé sur un pointeur vers un type inapproprié, 'dynamic_cast <>' retournera 'NULL'. Il n'y a pas de manière saine de donner de l'espace pour un 'D 'si vous avez seulement créé un nouveau' B'. Créez un nouveau 'D' en premier lieu, ou vivez avec le' B' que vous avez. –

0

b indique un objet de type B. Il ne peut pas devenir un D. Si vous voulez un D, ​​vous devez en allouer un et copier les champs de * b. Ne jamais penser aux choses d'un point de vue PHP, sauf si vous écrivez quelque chose en PHP. N'écrivez jamais rien en PHP.

+0

Son genre de câblé pour modéliser C++ compromis pour PHP. Mais la chose est Si elle a une solution avec C++ alors et seulement alors il a une solution dans n'importe quelle autre langue. et s'il n'a pas de solution en C++, il n'a pas de solution dans quoi que ce soit d'autre. –

+0

Il * a * une solution en C++. Cela n'a tout simplement pas une solution naïve comme vous l'avez dit. –

0

La reconstruction d'un objet de base vers un objet Dérivé n'est généralement pas possible. Tout d'abord, l'allocation allouait seulement de l'espace suffisant pour B et non pour D. Si vous allouiez suffisamment d'espace pour que D crée l'objet B (ce que vous ne faisiez pas actuellement, et c'est un peu difficile à faire de toute façon), alors pourrait utiliser des hacks pour «reconstruire» un objet comme celui-ci:

// EXTREME HACK, BE CAREFUL, AND USE WITH CARE 
// IF YOU DON'T UNDERSTAND IT, DON'T USE IT. 
// you should have allocated (sizeof (D)) space to your b pointer. 
D* d_object = new (b) D(B(*b)); 
// you should consider any previous pointer pointing toward the old B* as dangling. 
+0

Bien que cela puisse fonctionner, il serait plus facile, plus clair et moins sujet aux erreurs de faire simplement D * d = new D (* b); –

+0

Vous devez avoir un constructeur de copie sur 'D' qui prend' B' –

+0

J'ai pensé qu'il devait être là par souci d'exhaustivité. Peut-être utile à quelqu'un d'autre qui s'arrête là depuis google – BatchyX