c++ - 我想创建不同对象的共享 ptr 向量
问题描述
您有 2 个类 Cats 和 Dogs,需要创建一个共享指针向量来存储这 2 个类的数据。提示:多态性并记住类可以有相似的字段。
所以这就是我到目前为止所做的。我想插入shared_ptr
vector
所有信息Cats
和Dogs
课程,但我不知道如何。我只设法vector
从基类中插入数据。
#include <iostream>
#include <vector>
#include <memory>
class Animal
{
protected:
int tip;
std::string name;
int age;
public:
Animal(int t, std::string n, int a): tip(t), name(n), age(a) {}
friend std::ostream& operator<<(std::ostream& os, const Animal& a)
{
os << "Name: " << a.name << std::endl;
os << "Age: " << a.age << std::endl;
return os;
}
};
class Cats: public Animal
{
std::string race;
std::string pref_food;
public:
Cats(int t = 0, std::string n = "", int a = 0, std::string r = "", std::string mnprf = ""):
Animal(t, n, a), race(r), pref_food(mnprf) {}
friend std::ostream& operator<<(std::ostream& os, const Cats& c)
{
// auto n = static_cast<Animal> (c);
os << "Name: " << c.name << std::endl;
os << "Age: " << c.age << std::endl;
os << "race: " << c.race << std::endl;
os << "Fav food: " << c.pref_food << std::endl;
return os;
}
};
class Dog: public Animal
{
std::string disease;
std::string master;
public:
Dog(int t = 1, std::string n = "", int a = 0, std::string b = "", std::string s = "" ):
Animal(t, n, a), disease(b), master(s) {}
friend std::ostream& operator<<(std::ostream& os, const Dog& d)
{
os << "Name: " << d.name << std::endl;
os << "Age: " << d.age << std::endl;
os << "disease: " << d.disease << std::endl;
os << "master: " << d.master << std::endl;
return os;
}
};
template<typename T>
void add(std::vector<std::shared_ptr<Animal>>& vec, const T& a)
{
auto newptr = std::make_shared<Animal>(a);
vec.push_back(newptr);
}
int main()
{
std::vector<std::shared_ptr<Animal>> Animals;
Dog d(1,"Rex", 12, "idk", "Oscar");
Cats c(0,"Meaw", 11, "Sfinx", "Catfood");
add(Animals,d);
add(Animals,c);
for(auto i: Animals)
{
std::cout << *i;
}
}
解决方案
您的代码存在一些问题:
Animal
缺乏任何virtual
方法。至少,它需要一个virtual
析构函数,以便在调用其持有的指针时正确调用Cats
and的析构函数。Dog
shared_ptr<Animal>
delete
Animal*
add()
正在创建一个Animal
具体的实例,而不管T
. 所以你vector
只包含真实的Animal
物体。add()
需要创建一个实例来T
代替。当派生自时,std::shared_ptr<T>
可以将A分配给 a 。当然,是多余的,可以直接创建新对象并将其添加到其上而根本不使用。std::shared_ptr<Animal>
T
Animal
add()
main()
vector
add()
当
main()
调用operator<<
anAnimal
时,它不会调用operator<<
定义的Cats
orDog
,只会调用定义的operator<<
byAnimal
。这可以通过调用并覆盖operator<<
的方法来解决。当基类也有.Animal
virtual
Cats
Dog
operator<<
operator<<
试试这个:
#include <iostream>
#include <vector>
#include <memory>
class Animal
{
protected:
int tip;
std::string name;
int age;
public:
Animal(int t, std::string n, int a): tip(t), name(n), age(a) {}
virtual ~Animal() {}
virtual void print(std::ostream& os) const
{
os << "Name: " << name << std::endl;
os << "Age: " << age << std::endl;
}
friend std::ostream& operator<<(std::ostream& os, const Animal& a)
{
a.print(os);
return os;
}
};
class Cat : public Animal
{
std::string race;
std::string pref_food;
public:
Cat(int t = 0, std::string n = "", int a = 0, std::string r = "", std::string mnprf = ""):
Animal(t, n, a), race(r), pref_food(mnprf) {}
void print(std::ostream& os) const override
{
Animal::print(os);
os << "race: " << race << std::endl;
os << "Fav food: " << pref_food << std::endl;
}
};
class Dog : public Animal
{
std::string disease;
std::string master;
public:
Dog(int t = 1, std::string n = "", int a = 0, std::string b = "", std::string s = ""):
Animal(t, n, a), disease(b), master(s) {}
void print(std::ostream& os) const override
{
Animal::print(os);
os << "disease: " << disease << std::endl;
os << "master: " << master << std::endl;
}
};
template<typename T>
void add(std::vector<std::shared_ptr<Animal>> &vec, const T &a)
{
auto newptr = std::make_shared<T>(a);
vec.push_back(newptr);
}
int main()
{
std::vector<std::shared_ptr<Animal>> Animals;
Dog d(1,"Rex", 12, "idk", "Oscar");
Cat c(0,"Meaw", 11, "Sfinx", "Catfood");
add(Animals, d);
add(Animals, c);
/* alternatively:
Animals.push_back(std::make_shared<Dog>(1,"Rex", 12, "idk", "Oscar"));
Animals.push_back(std::make_shared<Cat>(0,"Meaw", 11, "Sfinx", "Catfood"));
*/
for(auto &i: Animals)
{
std::cout << *i;
}
return 0;
}
输出:
Name: Rex
Age: 12
disease: idk
master: Oscar
Name: Meaw
Age: 11
race: Sfinx
Fav food: Catfood
推荐阅读
- r - R生成带有空格的标签
- sql - 根据当天的第一次登录计算员工班次
- python - 我不明白为什么python中的googletrans不起作用,它给出错误:AttributeError:'NoneType'对象没有属性'group'
- c# - C# Xaml WebBrowser.DocumentText Youtube 错误
- linux - Bpftrace 单行命令在 ubuntu 18.04 上不起作用
- pandas - 如何规范化一个熊猫数据框的日期列(ValueError:无法将字符串转换为浮点数:'17-Aug-20 00:00:00')
- django - Django collectstatic 权限被 docker-compose 拒绝
- html - Why dots in the icons?
- python - 如何从数据框列中的字符串中删除日期?
- java - groovy 与 Java 中的 Hashmap