我想创建一个维护多态容器的 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
中维护的动态分配的宠物。为了避免这种情况,我想使用智能指针。但是,在我能够正确、干净地实现此类代码之前,有一些问题需要澄清。
需要有关以下问题的帮助。提前致谢。
- 我应该使用
std::unique_ptr
还是std::shared_ptr
?或者在什么情况下应该使用 std::unique_ptr 或 std::shared_ptr ?或者我应该重新使用原始指针? - 如果我选择使用
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/