2013-05-06 37 views
6

Tôi đang cố gắng tìm ra cách tốt nhất để giữ một con trỏ đến một phần tử trong một vector vừa được tạo ra và thêm vào các biến thành viên vector:Trả về một con trỏ đến một yếu tố vector

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

Các trình biên dịch đúng cho tôi một cảnh báo kể từ khi tôi trả về địa chỉ của một đối tượng được tạo trên ngăn xếp, và đối tượng đó sẽ đi ra ngoài phạm vi khi hàm kết thúc. Tuy nhiên, đối tượng sống trên vector, phải không?

Vì vậy, tôi có nên bỏ qua cảnh báo hoặc có cách nào tốt hơn để thực hiện việc này không?

Trả lời

10

Tuy nhiên, đối tượng sống trong vectơ, phải không?

Không, bản sao của nó. Bạn muốn trả lại địa chỉ của bản sao.

return &m_children.back(); 

Tuy nhiên, bạn không nên lưu con trỏ vào đối tượng nằm trong vectơ. Vì khi vector cần phân bổ lại, con trỏ sẽ bị vô hiệu. Có lẽ bạn nên lưu trữ con trỏ (tốt hơn là con trỏ thông minh) trong vector của bạn để thay thế.

Ví dụ:

// 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

điểm tốt, cảm ơn – johnbakers

+0

+1 cho ý tưởng lưu trữ con trỏ thông minh trong vectơ. – taocp

+0

có, tôi sẽ sử dụng 'std :: vector > m_children;' thay vì – johnbakers

0

Tuy nhiên, đối tượng sống mãi trong vector, phải không?

Khi bạn đẩy vào vectơ, nó thực sự đẩy copies của đối tượng, chứ không phải chính đối tượng đó, vào vectơ. Đồ đựng STL không copy in, copy out. Tuy nhiên, như được trình biên dịch chỉ ra, bạn không nên return the address of an object created on the stack.

0

Khi thêm nó vào std :: vector, về bản chất bạn đang thực hiện một bản sao. Bạn nên trả về tham chiếu đến đối tượng được lưu trữ trong vectơ.

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

Chà, điều đó làm tôi ngạc nhiên, nhưng tôi thực sự thấy các dấu ngoặc khiến việc đọc lần đầu tiên khó khăn hơn. – chris

0

Đối tượng không chính xác sống trong vector, kể từ khi bạn đang push_back ing nó, bạn đang làm cho một bản sao của nguyên tố này.

Mã này có thể làm việc nếu bạn thay đổi sự trở lại bằng một cái gì đó như thế (theo mẫu Ryan thực sự sẽ đơn giản hơn):

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

Bằng cách đó, bạn đang có hiệu quả trả về một con trỏ đến một yếu tố sống trong vector của bạn .

Các vấn đề liên quan