2010-02-26 22 views
5

È possibile anche questo scenario?Creare un'istanza di classe derivata da un'istanza di classe base senza conoscere i membri della classe

class Base 
{ 
    int someBaseMemer; 
}; 

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

    Derived(T* baseInstance); 
}; 

Calcio:

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

Il valore di pDerived-> someBaseMemer dovrebbe essere equeal a pBase-> someBaseMember e simili con altri elementi di base.

+3

Perché vuoi una cosa così contorta? – GManNickG

+0

StackOverflowException? LOL .... Su una nota seria ... questo non verrà compilato. –

+0

@Elite: In realtà, lo sarà, se cambierai i membri in pubblico. Non lo rende meno terrificante. –

risposta

3

Perché non dovresti finire di scrivere e compilare il codice?

class Base 
{ 
public: // add this 
    int someBaseMemer; 
}; 

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

    Derived(T* baseInstance) 
     : T(*baseInstance) // add this 
    { return; } // add this 
}; 

Compilano e funzionano come specificato.

MODIFICA: O intendi che someNonBaseMemer deve essere uguale a someBaseMemer?

+0

Derivato (T * baseInstance): T (* baseInstance) è la soluzione.Ho provato T (baseInstance) e mi sono bloccato sull'errore del compilatore. Messaggi di errore del compilatore che coinvolgono modelli es. SomeClass :: NestedClass :: blablah dammi i brividi. Grazie. –

+0

C'è stata un'altra buona risposta qui, ma è stata cancellata. Non so perché. Derivato (const T e baseInstance): T (baseInstance) era anche un buon suggerimento, ma non per il mio caso particolare. Esempio nella mia domanda è solo un piccolo pezzo di roba più grande. –

4

Perché si desidera derivare e passare il puntatore di base allo stesso tempo? Scegli uno, niente ti impedisce di averli entrambi. Utilizzare l'ereditarietà per fare il lavoro per voi:

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 

Anche se non è il meglio delle scelte come design.

+0

Mi sorprende il fatto che le persone desiderose di votare rispondano al punto. Qual è il punto di un costruttore Derivato (int, int) quando la classe Base ha più membri? Nella tua classe di esempio Derivato: Base pubblica sarebbe meglio, poiché la classe derivata deve riconoscere i membri della classe Base. Eppure non risponde ancora alla mia domanda. –

+1

Sfortunatamente mi manca il mio punto, sfortunatamente, che consisteva nel lasciare che il compilatore eseguisse la copia. Il tuo esempio è un disastro - che non aiuta affatto a capire il tuo punto di vista. – dirkgently

+0

Per fortuna c'era qualcuno in grado di capire il mio casino e rispondere alla mia domanda. –

1

Declare someBaseMemr come pubblico o modificare la dichiarazione class-struct:

class Base 
{ 
    public: 
    int someBaseMemer; 
}; 

OR 

struct Base 
{ 
    int someBaseMemr; 
}; 

Ricordate che un class ha private l'accesso a tutti i membri ed i metodi di default. A struct fornisce l'accesso public per impostazione predefinita.

Inoltre, tutte le classi derivate devono avere l'ereditarietà public da Base.

+0

La tecnica del poster è uno schema che consente di modificare le classi base o il percorso di derivazione della classe derivata. Ho usato anche questa tecnica. –

Problemi correlati