为什么智能指针 vector 不与 item 实现的接口(interface)协变?例如如果我有一个指向狗的指针 vector ,为什么我不能将它用作指向 iAnimal 的指针 vector ?
#include <iostream>
#include <memory>
#include <string>
#include <vector>
struct iAnimal
{
virtual std::string speak() const = 0;
};
struct iMammal : public iAnimal
{
virtual std::string speak() const = 0;
virtual int legs() const = 0;
};
struct Dog : public iMammal
{
std::string speak() const
{
return "WOOF!";
}
int legs() const
{
return 4;
}
};
void giveMammals(std::vector<std::shared_ptr<iMammal>> an)
{
for (const auto x : an)
{
x->legs();
}
}
void giveAnimals(std::vector<std::shared_ptr<iAnimal>> an)
{
for (const auto x : an)
{
x->speak();
}
}
int main()
{
std::vector<std::shared_ptr<Dog>> vec1 = { std::make_shared<Dog>() };
std::vector<std::shared_ptr<iMammal>> vec= { std::make_shared<Dog>() };
giveAnimals(vec);
giveMammals(vec1);
return 0;
}
最佳答案
原因是您提议的那种代码很容易被利用来做很多令人讨厌的事情。举个例子,让我们简单地看看,如果这段代码合法(但不合法),则可以将 Cat
插入到 Dog
的 vector 中。
struct Cat : public iMammal {
std::string speak() const
{
return "meow.";
}
int legs() const
{
return 4;
}
};
void giveAnimals(std::vector<std::shared_ptr<iAnimal>> & an) {
//This, on its own, is perfectly legal given the type that `an` is.
an.emplace_back(std::make_shared<Cat>());
for (auto const& x : an)
{
x->speak();
}
}
int main() {
std::vector<std::shared_ptr<Dog>> vec = { std::make_shared<Dog>() };
giveAnimals(vec);//Uhhhh.......
for(auto const& dog_ptr : vec) {
dog_ptr->speak();//These are not all going to bark!
}
}
std::vector
(和其他类似的库结构)完全禁止这种转换以防止出现这样的错误。
关于c++ - 为什么智能指针 vector 不是指向实现与该接口(interface)协变的接口(interface)的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51502834/