Мы должны создавать классы животных, которые наследуются от классов разных типов животных, то есть класс Dog будет наследоваться от класса Carnivore, который будет наследоваться от класса Mammal. Я пытался использовать мои классы в моей собственной главной функции, и они распечатывали то, что они должны сказать, и их имя, но когда я запускаю свои классы с основным файлом моего учителя, он сообщает мне трассировку стека дампинга.
#include <iostream>
#include <string>
#include <typeinfo>
#include <vector>
using namespace std;
class Mammal {
public:
virtual string say() = 0;
virtual string name() = 0;
};
class Carnivore : public Mammal {
public:
virtual string say() = 0;
virtual string name() = 0;
};
class Canid : public Carnivore{
public:
virtual string say() = 0;
virtual string name() = 0;
};
class Dog : public Canid{
public:
string say(){
return "bark";
}
string name(){
return "dog";
}
};
class Fox : public Canid{
public:
Fox(){
spoke = "ay";
}
std::string say(){
spoke += spoke;
return spoke;
}
std::string name(){
return "fox";
}
private:
std::string spoke;
};
class Feline : public Canid{
public:
virtual string say() = 0;
virtual string name() = 0;
};
class Cat : public Feline{
public:
std::string say(){
return "moew";
}
std::string name(){
return "cat";
}
};
class Rodent : public Mammal{
public:
virtual string say() = 0;
virtual string name() = 0;
};
class Mouse : public Rodent{
public:
std::string say(){
return "squeak";
}
std::string name(){
return "mouse";
}
};
Mammal* MammalFactory(const std::type_info& ti){
if(ti == typeid(Dog)){
cout << "running dog" << endl;
Dog D;
Mammal* dog = &D;
return dog;
}
else if (ti == typeid(Fox)){
cout << "running fox" << endl;
Fox F;
Mammal* fox = &F;
return fox;
}
else if (ti == typeid(Cat)){
cout << "running cat" << endl;
Cat C;
Mammal* cat = &C;
return cat;
}
else if (ti == typeid(Mouse)){
cout << "running mouse" << endl;
Mouse M;
Mammal* mouse = &M;
return mouse;
}
else{
return NULL;
}
}
int main(){
int score = 90;
std::vector<Mammal*> mammals;
mammals.push_back(MammalFactory(typeid(Dog)));
mammals.push_back(MammalFactory(typeid(Cat)));
mammals.push_back(MammalFactory(typeid(Mouse)));
Mammal* fox = MammalFactory(typeid(Fox));
mammals.at(0)->name();
for (std::vector<Mammal*>::iterator I = mammals.begin(); I != mammals.end(); ++I) {
std::cout<<(*I)->name()<<" goes "<<(*I)->say()<<'\n';
}
//Check animal names
if (mammals.at(0)->name() != "dog") {
std::cout<<"Dog's name is incorrect! -10\n";
score -= 10;
}
if (mammals.at(1)->name() != "cat") {
std::cout<<"Cat's name is incorrect! -10\n";
score -= 10;
}
if (mammals.at(2)->name() != "mouse") {
std::cout<<"Mouse's name is incorrect! -10\n";
score -= 10;
}
if (fox->name() != "fox") {
std::cout<<"Fox's name is incorrect! -10\n";
score -= 10;
}
//Fox part
std::string thing1 = fox->say();
std::string thing2 = fox->say();
std::cout<<"What does the "<<fox->name()<<" say?\n";
std::cout<<thing1<<"!\n";
std::cout<<thing1<<"!\n";
std::cout<<thing1<<"!\n";
std::cout<<"What does the "<<fox->name()<<" say?\n";
std::cout<<thing2<<"!\n";
std::cout<<thing2<<"!\n";
std::cout<<thing2<<"!\n";
if (thing1 == thing2) {
std::cout<<"Foxes don't say the same thing twice!\n";
score -= 10;
}
for (std::vector<Mammal*>::iterator I = mammals.begin(); I != mammals.end(); ++I) {
delete *I;
}
delete fox;
return 0;
}
В дополнение к тому, что деструктор не является виртуальным, вы возвращаете адрес локальной переменной. Это неопределенное поведение.
Mammal* MammalFactory(const std::type_info& ti)
{
if(ti == typeid(Dog))
{
cout << "running dog" << endl;
Dog D;
Mammal* dog = &D;
return dog; // so what happens to D when MammalFactory returns?
}
}
Вы делаете ту же ошибку для всех других производных классов. Как только эта функция вернется, больше не будет «D». Он превратился в клуб дыма, и вы возвращаете адрес этой переменной, которой больше не существует.
Либо создай нового Млекопитающего (return new Dog;
) или придумать способ создать Dog и вернуть тот, который не является локальным (опять же, проблема не только в этом классе, но и во всех других наших классах).
Некоторые проблемы: