c++ - 错误: no matching function for call to 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)'

标签 c++ class inheritance

您好,我需要帮助修复 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

Live Demo on coliru

使用 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

Live Demo on coliru

销毁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/

相关文章:

c++ - 2 个头文件中的 2 个类

c++ - 编号的唯一文件

c++ - 遍历 Vector 中结构的成员时出错

PHP 如何获取带有类和命名空间路径的方法名称作为字符串?

Java 类变量等于相同的值

c++ - 为具有多重继承的一种类型设置默认构造函数

scala - 以下 'illegal inheritance' (Scala 2.9.2) 背后的原因是什么?

java - 如何在 100 多个现有类中创建新的类变量?

c++ - CMake-Qt : linking to wrong versions

gcc 中的 C++11 thread_local - 备选方案