簡體   English   中英

這是在現代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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM