2013-04-02 16 views
5

Przepisuję aplikację za pomocą inteligentnych wskaźników C++ 11.C++ 11 inteligentne wskaźniki i polimorfizm

mam podstawową klasę:

class A {}; 

a klasą pochodny:

class B : public A { 
    public: 
    int b; 
}; 

mam inną klasę zawierającą wektor z A lub B obiektów:

class C { 
    public: 
    vector<shared_ptr<A>> v; 
}; 

Nie mam problemu z budowaniem C z obiektami klasy A (klasy bazowej), ale jak mogę je wypełnić obiektami B (klasa pochodna)?

Próbuję to:

for(int i = 0; i < 10; i++) { 
    v.push_back(make_shared<B>()); 
    v.back()->b = 1; 
}; 

I powraca kompilatora: błędach: 'klasa A' nie ma elementu o nazwie 'b'

+0

Co próbujesz zrobić? Wygląda na to, że traktowanie A jako polimorfizmu jest złym pomysłem, ponieważ nie wykorzystasz tego. –

+2

Nie chodzi o inteligentne wskaźniki, niewłaściwie używasz polimorfizmu. Zastąp członka publicznego b funkcją wirtualną (prawdopodobnie, pobierz i ustaw funkcje). –

+0

Uprościliśmy klasy. W ich prawdziwej formie polimorfizm ma sens. –

Odpowiedz

10

But how can I fill it with B (derived class) objects?

Jesteś wypełnienie go z (wskazówkami) obiektami B. Jednak statyczny typ wskaźników odnosi się do klasy bazowej A, więc nie można ich bezpośrednio użyć, aby uzyskać dostęp do jakichkolwiek elementów klasy pochodnej.

W swoim prostym przykładzie, można po prostu trzymać trzymać wskaźnik do B i używać:

std::shared_ptr<B> b = make_shared<B>(); 
b->b = 1; 
v.push_back(b); 

Jeśli nie masz dostępu do oryginalnego wskaźnika, a następnie trzeba będzie jakiś rodzaj polimorfizmu :

  • użycie static_cast<B*>(v.back().get())jeśli wiesz, że wszystkie obiekty mają typ B
  • użyć funkcji wirtualnego lub dynamic_cast (która wymaga, aby klasa podstawowa zawierała funkcję wirtualną do działania), jeśli obiekty mogą mieć różne typy
3
for(int i = 0; i < 10; i++) { 
    auto bptr = make_shared<B>(); 
    v.push_back(bptr); 
    bptr->b = 1; 
}; 
+1

Dziękuję za odpowiedź. To prawda, ale wyjaśnienie Mike'a Seymoura pomogło mi zrozumieć dlaczego. –