c++ - 使用智能指针制作多态容器的正确方法是什么?

标签 c++ polymorphism c++17 smart-pointers

我想创建一个维护多态容器的 C++ 类。例如, vert 可以保存当前正在接受治疗的宠物的列表。如果我们使用原始指针,我们可以如下定义一个 vet。

class Vet{
    std::vector<Pet*> pets;
public:
    void addPet(Pet* pet);  
};

我们可以按如下方式添加宠物。

Vet vet;
vet.addPet(new Dog{});
vet.addPet(new Cat{});

在这种情况下,Vet类的析构函数应该负责删除pets中维护的动态分配的宠物。为了避免这种情况,我想使用智能指针。但是,在我能够正确、干净地实现此类代码之前,有一些问题需要澄清。 需要有关以下问题的帮助。提前致谢。

  1. 我应该使用 std::unique_ptr 还是 std::shared_ptr?或者在什么情况下应该使用 std::unique_ptr 或 std::shared_ptr ?或者我应该重新使用原始指针?
  2. 如果我选择使用 std::unique_ptr addPet 方法的方法签名及其实现是什么?
  • 选择 1-1)
void addPet(std::unique_ptr<Pet> pet){
    pets.push_back(std::move(pet));
}
  • 选择 1-2)
void addPet(std::unique_ptr<Pet>& pet){
    pets.push_back(std::move(pet));
}

只有当我按如下方式构造宠物时,此选择才有效。

std::unique_ptr<Pet> dog = std::make_unique<Dog>();
vet.addPet(dog);
  • 选择 1-3)
void addPet(PetType pet){
    if(pet==PetType::Dog) pets.push_back(std::make_unique<Dog>());
    //
}
  • 如果我选择使用 std::shared_ptr addPet 方法的方法签名及其实现是什么?
    • 选择2-1)
    void addPet(std::shared_ptr<Pet> pet){
        pets.push_back(std::move(pet));
    }
    
    • 选择2-2)
    void addPet(const std::shared_ptr<Pet>& pet){
        pets.push_back(pet);
    }
    

    最佳答案

    假设您确实想在外部创建宠物,最好的方法是 unique_ptr 并按值传递它,如下所示:

    void addPet(std::unique_ptr<Pet> pet);
    

    unique_ptr 因为您告诉读者只有一个所有者。

    按值,因为这需要您在调用 addPet 时使用临时或显式移动 unique_ptr。向外界明确表明您正在移动/转移所有权。

    例如你可以这样做

    auto pet = std::make_unique<Dog>();
    vet.addPet(std::move(pet)); // move is required, making it explicit that ownership is transferred
    

    vet.addPet(std::make_unique<Dog>());
    

    如果您在 addPet 中接受对 unique_ptr 的引用,调用者将不知道在调用 addPet 后提供的参数是否仍然有效 或不。

    Here这是一篇关于该主题的精彩帖子。

    关于c++ - 使用智能指针制作多态容器的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73529816/

    相关文章:

    c++ - openCV形状缺陷识别

    c++ - 使用opencv循环像素

    c++ - 比较字符串的 GetLine 工作一次然后比较不起作用

    c++ - 摆动/摆动相机

    java - 关于Java多态性的问题

    java - 这段代码的含义是什么?与多态性相关

    java - 如何避免多重继承?

    c++ - 为什么函数返回不移动 vector ?

    c++ - 如何使用 optional 元素初始化 C++17 对 vector

    c++ - 如何让map.emplace在c++17中自动选择构造函数?