您好,我需要帮助修复 C++ 的此错误。 我正在尝试创建一个返回包含宠物对象的 vector 的函数。 我尝试使用推回,仍然无法编译。 我有很多其他类(猫、狗、鱼等),它们也继承了宠物基类。
这是我的函数的一个片段。
std::vector<Pet*> make_pets() {
//why doesn't this work?
std::vector<Pet*> newVector {Cat(), Dog()};
return newVector;
//newVector.push_back(c);
}
最佳答案
操作代码中的错误:
std::vector<Pet*> newVector {Cat(), Dog()};
Cat()
创建 Cat
的临时实例。类型为Cat
(或Cat&
)。
std::vector<Pet*>
的元素类型是 Pet*
这是不兼容的。应用地址运算符( &Cat()
)会使事情变得更糟。虽然类型现在会匹配(如果 Cat*
是从 Pet*
派生的, Cat
可以分配给 Pet
), Cat()
创建一个临时实例。它没有提供足够的生命周期,因为它在表达式结束时自动销毁,这会在 std::vector
中留下一个悬空指针。 .
要解决此问题,new
可以使用:
std::vector<Pet*> newVector {new Cat(), new Dog()};
coliru 上的 MCVE:
#include <iostream>
#include <memory>
#include <vector>
struct Pet {
virtual ~Pet() = default;
virtual const char* what() const = 0;
};
struct Cat: public Pet {
virtual const char* what() const override { return "cat"; }
};
struct Dog: public Pet {
virtual const char* what() const override { return "dog"; }
};
std::vector<Pet*> make_pets()
{
std::vector<std::unique_ptr<Pet>> vec{ new Cat(), new Dog() };
return vec;
}
int main()
{
std::vector<std::unique_ptr<Pet>> pets = make_pets();
std::cout << "Pets:\n";
for (const Pet *pPet : pets) std::cout << pPet->what() << '\n';
for (const Pet *pPet : pets) delete pPet;
}
输出:
Pets:
cat
dog
使用 new
创建实例导致这些实例必须使用 delete
显式销毁。只是清除std::vector<Pet*>
pets
相反,会使实例未被删除并丢失——内存泄漏。
std::unique_ptr的用法(如@user4581301推荐)有点棘手。因为 std::unique_ptr
的一个实例是唯一拥有/持有指针的人,它不能被复制或分配,而只能被移动。经过一番摆弄,我在 coliru 上得到了一个 mcve:
#include <iostream>
#include <memory>
#include <vector>
struct Pet {
virtual ~Pet() = default;
virtual const char* what() const = 0;
};
struct Cat: public Pet {
virtual const char* what() const override { return "cat"; }
};
struct Dog: public Pet {
virtual const char* what() const override { return "dog"; }
};
std::vector<std::unique_ptr<Pet>> make_pets()
{
std::vector<std::unique_ptr<Pet>> vec;
vec.emplace_back(std::make_unique<Cat>());
vec.emplace_back(std::make_unique<Dog>());
return vec;
}
int main()
{
std::vector<std::unique_ptr<Pet>> pets = make_pets();
std::cout << "Pets:\n";
for (const std::unique_ptr<Pet> &pPet : pets) std::cout << pPet->what() << '\n';
}
输出:
Pets:
cat
dog
销毁Pet
在这种情况下,实例不是问题。 std::unique_ptr<Pet>
允许在删除指针本身后立即删除受指点。
关于c++ - 错误: no matching function for call to 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58926355/