将 BASE-DERIVED class 存储在同一个容器中
Store BASE-DERIVED class in same container
我的概念(不是真实的)class 层次结构为:
struct Pet{};
struct Cat : Pet{};
struct Dog : Pet{};
对象如下:
Pet p("unknown");
Cat c("Kitty");
Dog D("Tommy");
现在如何将对象 p,c,d
存储在像 std::vector
这样的单个容器中。但我想不出办法。当我将 std::vector<Pet>
其他 class 切片时。我什至无法将它们作为指针存储在容器中,因为指针仍然具有不同的类型。
通常将它们放在同一个容器中的唯一原因是将它们用作基本类型,利用多态性根本不关心具体类型是什么。这需要使用虚拟方法。例如:
struct Pet {
virtual ~Pet();
virtual void speak(std::ostream &) const = 0;
};
Pet::~Pet() {}
struct Cat : public Pet {
virtual void speak(std::ostream &) const override;
};
void Cat::speak(std::ostream & o) const {
o << "Meow!\n";
}
struct Dog : public Pet {
virtual void speak(std::ostream &) const override;
};
void Dog::speak(std::ostream & o) const {
o << "Woof!\n";
}
现在我们有了一个虚拟方法 (speak(std::ostream&)
),我们可以通过指向 Pet
的指针调用它,而无需知道宠物的实际类型:
std::vector<std::unique_ptr<Pet>> pets;
pets.emplace_back(std::make_unique<Cat>());
pets.emplace_back(std::make_unique<Dog>());
for (auto const & pet : pets) {
pet->speak(std::cout);
}
显示:
Meow!
Woof!
如果您不能像这样将容器中的所有对象都视为基本实例,那么就没有理由将它们放在同一个容器中 - 这有什么意义?
我的概念(不是真实的)class 层次结构为:
struct Pet{};
struct Cat : Pet{};
struct Dog : Pet{};
对象如下:
Pet p("unknown");
Cat c("Kitty");
Dog D("Tommy");
现在如何将对象 p,c,d
存储在像 std::vector
这样的单个容器中。但我想不出办法。当我将 std::vector<Pet>
其他 class 切片时。我什至无法将它们作为指针存储在容器中,因为指针仍然具有不同的类型。
通常将它们放在同一个容器中的唯一原因是将它们用作基本类型,利用多态性根本不关心具体类型是什么。这需要使用虚拟方法。例如:
struct Pet {
virtual ~Pet();
virtual void speak(std::ostream &) const = 0;
};
Pet::~Pet() {}
struct Cat : public Pet {
virtual void speak(std::ostream &) const override;
};
void Cat::speak(std::ostream & o) const {
o << "Meow!\n";
}
struct Dog : public Pet {
virtual void speak(std::ostream &) const override;
};
void Dog::speak(std::ostream & o) const {
o << "Woof!\n";
}
现在我们有了一个虚拟方法 (speak(std::ostream&)
),我们可以通过指向 Pet
的指针调用它,而无需知道宠物的实际类型:
std::vector<std::unique_ptr<Pet>> pets;
pets.emplace_back(std::make_unique<Cat>());
pets.emplace_back(std::make_unique<Dog>());
for (auto const & pet : pets) {
pet->speak(std::cout);
}
显示:
Meow!
Woof!
如果您不能像这样将容器中的所有对象都视为基本实例,那么就没有理由将它们放在同一个容器中 - 这有什么意义?