2013-05-06 14 views
6

Próbuję dowiedzieć się, najlepszy sposób, aby utrzymać wskaźnik do elementu w wektorze, który właśnie został utworzony i dodany do państw zmiennym wektorze:Wracając wskaźnik do elementu wektora

SceneGraphNode* addChild(std::string name){ 
    SceneGraphNode child(this,name); 
    m_children.push_back(child); 
    return &child; 
} 

The kompilator słusznie daje mi ostrzeżenie, ponieważ zwracam adres obiektu utworzonego na stosie i obiekt ten wykracza poza zakres, gdy funkcja się kończy. Jednak obiekt nadal żyje w vector, prawda?

Czy powinienem zignorować ostrzeżenie lub czy istnieje lepszy sposób na zrobienie tego?

Odpowiedz

10

Jednak obiekt żyje w wektorze, prawda?

Nie, kopia tego ma. Chcesz zwrócić adres kopii.

return &m_children.back(); 

Jednak nie jest dobrym pomysłem przechowywanie wskaźnika do obiektu znajdującego się w wektorze. Ponieważ gdy wektor musi się ponownie przesłać, wskaźnik zostanie unieważniony. Być może zamiast tego należy przechowywać wskaźniki (najlepiej inteligentne wskaźniki) w swoim wektorze.

Na przykład:

// in your class 
std::vector<std::unique_ptr<SceneGraphNode>> m_children; 

SceneGraphNode* addChild(std::string name) 
{ 
    std::unique_ptr<SceneGraphNode> child(new SceneGraphNode(this,name)); 
    m_children.push_back(std::move(child)); 
    return m_children.back().get(); 
} 
+0

dobre punkty, dzięki – johnbakers

+0

+1 za pomysł przechowywania inteligentnego wskaźnika w wektorze. – taocp

+0

tak, zamierzam użyć 'std :: vector > m_children;' zamiast – johnbakers

0

Jednak obiekt żyje w wektorze, prawda?

Po wciśnięciu do wektora, faktycznie wepchnie on do obiektu obiekty, a nie sam obiekt, w postaci copies. Pojemniki STL mają numer copy in, copy out. Jednak, jak wskazuje kompilator, nie powinieneś/powinnaś return the address of an object created on the stack.

0

Podczas dodawania do wektora std :: zasadniczo robisz kopię. Powinieneś zwrócić referencję do obiektu przechowywanego w wektorze.

return &(m_children.back()); 
+0

Wow, zaskakuje mnie, ale uważam, że nawiasy utrudniały czytanie po raz pierwszy. – chris

0

obiekt nie dokładnie żyć w wektorze, ponieważ kiedy jesteś push_back ing go, robisz kopię tego elementu.

Ten kod może działać, jeśli zmienił deklarację coś takiego (postać Ryana rzeczywiście byłoby prostsze):

return &m_children[m_children.size() - 1]; 

ten sposób, jesteś skutecznie powracającego wskaźnik do elementu mieszka w wektorze .

Powiązane problemy