Почему мой код выдает ошибку stackdump при запуске?

Мы должны создавать классы животных, которые наследуются от классов разных типов животных, то есть класс 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;
}

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 и вернуть тот, который не является локальным (опять же, проблема не только в этом классе, но и во всех других наших классах).

0

Другие решения

Некоторые проблемы:

  • Отсутствие виртуального деструктора в базовом классе.
  • возврате свисающие указатели, указатели на локальные объекты, которые перестали существовать.
  • Экспоненциальное увеличение потребления памяти у лис, так как они лают.
0

По вопросам рекламы [email protected]