![](/img/trans.png)
[英]Are there any valid use cases to use new and delete, raw pointers or c-style arrays with modern C++?
[英]Is this use of raw pointers in modern C++ bad practice?
我想要保存一個沒有對象切片的Base類實例的向量(這樣我也可以存儲沒有問題的Base的子實例),同時保持多態行為,而不是通過復制值而是通過引用添加到列表中。
請考慮以下源文件:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class Entity
{
public:
Entity(){this->edited = false;}
virtual std::string name() = 0;
bool edited;
};
class Player: public Entity
{
public:
Player(): Entity(){}
std::string name(){return "player";}
};
int main()
{
std::vector<Entity*> entities;
Player p;
entities.push_back(&p);
entities.at(0)->edited = true;
Entity* ent = entities.at(0);
std::cout << "ent = " << ent->name() << ", edited = " << ent->edited << ".\n";
return 0;
}
我獲得以下輸出:
ent = player, edited = 1.
當輸出顯示(通過打印出“播放器”並顯示“已編輯”中的更改)時,由於原始指針而保持多態行為,並且我能夠毫無問題地編輯列表成員。
澄清我在問什么:我可以使用std :: reference_wrapper來實現完全相同的行為嗎? 當我嘗試使用reference_wrapper時,由於需要指針來實現這種多態行為,所以無法實現相同的行為? 如果reference_wrappers不是一個可行的選擇,雖然我完全知道我添加到向量中的Player實例是一個堆棧變量,但是使用shared_ptr是否明智? 在我的特定示例中,我傾向於使用shared_ptr,因為我想要向量的成員共享所有權。 有沒有更好的方法來實現這種行為?
在現代c ++中,非擁有指針很好。 但是如果你的指針是擁有的 ,你最好有一個很好的理由使用原始指針而不是智能指針。 即使在最壞的情況下,您仍然可以編寫自己的智能指針。 您的示例是非擁有指針。
使用std::reference_wrapper<T>
在這里沒有任何幫助。 我已經包含了你的例子,修改后使用它。 請注意,直接操作向量中的元素會稍微煩一些。
int main()
{
std::vector<std::reference_wrapper<Entity>> entities;
Player p;
entities.push_back(p);
entities.front().get().edited = true;
Entity & ent = entities.front();
std::cout << "ent = " << ent.name() << ", edited = " << ent.edited << ".\n";
return 0;
}
原始指針只是一種工具,就像c ++提供的許多其他工具一樣。 當它是正確的工具時,不要害怕使用它。 現代c ++帶來的最重大變化是它已經取消了擁有原始指針。 經驗法則是,如果你必須記得delete
你做錯了。
請注意, std::vector<T>::front()
是獲取第一個元素的首選方法,當您知道索引有效時std::vector::at
不建議使用std::vector::at
。
那里沒有錯。 它可能是壞的唯一情況是你將開始分配實體對象並忘記刪除它們。
std::vector<Entity*> entities;
entities.push_back(new Player());
// Somthing that may throw exception
delete entities.at(0)
但這是一個有點不同的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.