6
votes

Créer une instance de classe dérivée à partir d'une instance de classe de base sans connaître les membres de la classe

Ce scénario est-il même possible?

Base* pBase = new Base();
pBase->someBaseMemer = 123; // Some value set
Derived<Base>* pDerived = new Derived<Base>(pBase);


5 commentaires

Pourquoi voulez-vous une telle chose contournée?


StackoverflowException? Lol .... sur une note sérieuse ... cela ne compilera pas.


@Elite: En fait, ce sera, si vous changez aux membres pour être public. Ne rend pas moins terrifiant cependant.


Il me semble que vous pouvez utiliser ceci pour créer une fusion d'objets qui ont la fonctionnalité que vous souhaitez personnellement tout en conservant leur propre fonctionnalité. Imaginez avoir une collection qui, peu importe quoi, a la possibilité d'appeler lecture () et écrire () et ce qui est écrit ou lue dépend du type de périphérique également (port série? Fichier? Descripteur de fichier?). Semble comme un mauvais design, cependant.


Cela semble être une application simple de CRTP plus la copie à partir d'une instance de classe de base et de transmettre l'objet de base (à copier) au CTOR dérivé comme une référence au lieu d'un pointeur est plus courant en C ++. en.wikipedia.org/wiki/curiosité_recurring_template_pattern


3 Réponses :


4
votes

Pourquoi voudriez-vous dériver et transmettre le pointeur de base en même temps? Choisissez soit, rien ne vous empêche d'avoir les deux. Utilisez l'héritage pour faire le travail pour vous:

class Base
{
  public:
    Base(int x) : someBaseMemer(x) {}
  protected:      // at least, otherwise, derived can't access this member
    int someBaseMemer;
};

template<class T>
class Derived : public T
{
  int someNonBaseMemer;

  public:
  Derived(int x, int y) : someNonBaseMemer(y), T(x) {}
};

Derived<Base> d(42, 32); // usage


3 commentaires

Cela me surprend comment les gens impatients doivent voter des réponses au point de manquer. Quel est le point d'un constructeur dérivé (int, int) lorsque la classe de base a plus de membres? Dans votre exemple de classe dérivé: la base publique serait mieux, car la classe dérivée doit reconnaître les membres de la classe de base. Pourtant, cela ne répond toujours pas à ma question.


Malheureusement, vous manquez tout ce qui me manquait, qui consistait malheureusement à laisser le compilateur faire la copie. Votre exemple est un gâchis - qui n'aide pas du tout à obtenir votre point de vue.


Heureusement, il y avait une personne capable de comprendre mon désordre et de répondre à ma question.



1
votes

déclarer quelquebasememr comme public ou modifier la déclaration de class à struct : xxx

N'oubliez pas que Une classe a privé accès à tous les membres et méthodes par défaut. Un struct fournit accès par défaut.

En outre, toutes les classes dérivées doivent avoir public héritage de base .


1 commentaires

La technique de l'affiche est un motif qui permet de changer les classes de base ou le chemin de dérivation de la classe dérivée. J'ai également utilisé cette technique.



3
votes

Pourquoi ne finiriez-vous pas écrire et compiler le code? XXX

Ceci compile et fonctionne comme indiqué.

Edit: ou voulez-vous dire que < Code> SomenonBasememememememememeur CertainBasememeur ?


2 commentaires

Dérive (T * BaseInstance): T (* BaseInstance) est la solution. J'ai essayé t (BaseInstance) et j'ai été bloqué sur l'erreur du compilateur. Messages d'erreur du compilateur impliquant des modèles, par exemple. Soméclass ::Class :: Blabla Donne-moi les rampes de chair. Merci.


Il y avait une autre bonne réponse ici, mais a été supprimée. Je ne sais pas pourquoi. Dérivé (const t & baseinstance): T (baseInstance) était également un bon indice, mais pas pour mon cas particulier. Exemple dans ma question est juste un petit morceau de plus gros choses.