2010-02-26 20 views
5

¿Es posible este escenario?Crear instancia de clase derivada de una instancia de clase base sin conocer los miembros de la clase

class Base 
{ 
    int someBaseMemer; 
}; 

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

    Derived(T* baseInstance); 
}; 

Objetivo:

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

El valor de pDerived-> someBaseMemer debe ser equeal a pBase-> someBaseMember y similares con otros miembros de base.

+3

¿Por qué quieres una cosa tan contorsionada? – GManNickG

+0

StackOverflowException? LOL ... En una nota seria ... esto no compilará. –

+0

@Elite: en realidad, si cambia los miembros para que sean públicos, lo hará. Sin embargo, no lo hace menos aterrador. –

Respuesta

3

¿Por qué no terminarías de escribir y compilar el código?

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 
}; 

Esto se compila y ejecuta según lo especificado.

EDITAR: ¿O quiere decir que someNonBaseMemer debe ser igual a someBaseMemer?

+0

Derivado (T * baseInstance): T (* baseInstance) es la solución.Intenté T (baseInstance) y me quedé atrapado en el error del compilador. Mensajes de error del compilador que incluyen plantillas, p. Ej. SomeClass :: NestedClass :: blablah me da escalofríos. Gracias. –

+0

Hubo otra buena respuesta aquí, pero se ha eliminado. No sé por qué. Derivado (const T & baseInstance): T (baseInstance) también fue una buena pista, pero no para mi caso particular. El ejemplo en mi pregunta es solo una pequeña parte de algo más grande. –

4

¿Por qué querría derivar y pasar el puntero de base al mismo tiempo? Elija cualquiera, nada le impide tener ambos. Use la herencia para hacer el trabajo por usted:

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 

Aunque no es la mejor opción como diseño.

+0

Me sorprende lo ansiosos que están las personas por votar las respuestas al error. ¿Cuál es el punto de un constructor Derived (int, int) cuando la clase Base tiene más miembros? En su clase de ejemplo Derivado: la base pública sería mejor, ya que la clase Derivada debe reconocer los miembros de la clase Base. Sin embargo, todavía no responde mi pregunta. –

+1

Desaprovecha por completo mi punto, desafortunadamente, que consistía en dejar que el compilador copiara. Tu ejemplo es un desastre, eso no ayuda en absoluto a expresar tu punto de vista. – dirkgently

+0

Afortunadamente había alguien capaz de entender mi problema y responder mi pregunta. –

1

Declarar someBaseMemr como público o cambiar la declaración del class a struct:

class Base 
{ 
    public: 
    int someBaseMemer; 
}; 

OR 

struct Base 
{ 
    int someBaseMemr; 
}; 

Recuerde que un classprivate tiene acceso a todos los usuarios y los métodos por defecto. A struct proporciona acceso public de forma predeterminada.

Además, todas las clases derivadas deben tener public herencia de Base.

+0

La técnica del póster es un patrón que permite cambiar las clases base o la ruta de derivación de la clase derivada. También he usado esta técnica. –

Cuestiones relacionadas