2010-02-26 27 views
5

Czy ten scenariusz jest nawet możliwy?Tworzenie instancji klasy pochodnej z instancji klasy podstawowej bez znajomości elementów klasy

class Base 
{ 
    int someBaseMemer; 
}; 

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

    Derived(T* baseInstance); 
}; 

Cel:

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

Wartość pDerived-> someBaseMemer powinny być equeal do pBase-> someBaseMember i podobnie z innymi członkami bazowych.

+3

Po co ci taka skrzywiona rzecz? – GManNickG

+0

StackOverflowException? LOL .... Poważnie mówiąc ... to się nie skomplikuje. –

+0

@Elite: Właściwie to będzie, jeśli zmienisz członków na publiczne. Nie czyni tego jednak mniej przerażającym. –

Odpowiedz

3

Dlaczego nie chcesz dokończyć pisania i kompilowania kodu?

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

Kompiluje się i działa zgodnie z podanymi wskazaniami.

EDYCJA: Czy masz na myśli, że someNonBaseMemer powinna być równa someBaseMemer?

+0

Pochodny (T * baseInstance): T (* baseInstance) jest rozwiązaniem.Próbowałem T (baseInstance) i utknąłem na błąd kompilatora. Komunikaty o błędach kompilatora obejmujące szablony, np. SomeClass :: NestedClass :: blablah daj mi gęsią skórkę. Dziękuję Ci. –

+0

Tutaj była jeszcze jedna dobra odpowiedź, ale została usunięta. Nie wiem dlaczego. Pochodny (const T & baseInstance): T (baseInstance) również było dobrą wskazówką, ale nie dla mojego konkretnego przypadku. Przykład w moim pytaniu to po prostu mały kawałek większych rzeczy. –

4

Dlaczego chcesz wyprowadzać i przekazywać wskaźnik bazowy w tym samym czasie? Wybierz, nic nie powstrzyma cię od posiadania obu. Użyj dziedziczenia, aby wykonać to zadanie:

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 

Chociaż nie jest to najlepszy wybór spośród projektów.

+0

Zaskakuje mnie, jak chętni ludzie mają głosować w górę odpowiedzi brakowało punktu. Jaki jest sens konstruktora Derived (int, int), gdy klasa Base ma więcej członków? W twojej przykładowej klasie Derived: public Base będzie lepsza, ponieważ klasa Derived musi rozpoznać członków klasy Base. Jednak wciąż nie odpowiada na moje pytanie. –

+1

Całkowicie tęsknisz za moim punktem, niestety, który polegał na umożliwieniu kompilatorowi skopiowania. Twój przykład to bałagan - to wcale nie pomaga, aby uzyskać lepszy punkt widzenia. – dirkgently

+0

Na szczęście był ktoś w stanie zrozumieć mój bałagan i odpowiedzieć na moje pytanie. –

1

Declare someBaseMemr jako publiczne lub zmienić deklarację class do struct:

class Base 
{ 
    public: 
    int someBaseMemer; 
}; 

OR 

struct Base 
{ 
    int someBaseMemr; 
}; 

pamiętać, że class ma private dostęp do wszystkich członków i metod domyślnie. Opcja struct zapewnia domyślnie dostęp do .

Ponadto wszystkie pochodne klasy powinny mieć dziedziczenie public z Base.

+0

Technika plakatu to wzorzec umożliwiający zmianę klas bazowych lub ścieżki pochodnej klasy pochodnej. Użyłem też tej techniki. –

Powiązane problemy