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

78
9

Мы должны делать классы животных, которые наследуются от классов разных типов животных, то есть класс 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 name is incorrect! -10\n";
score -= 10;
}
if (mammals.at(1)->name() != "cat") {
std::cout<<"Cat name is incorrect! -10\n";
score -= 10;
}
if (mammals.at(2)->name() != "mouse") {
std::cout<<"Mouse name is incorrect! -10\n";
score -= 10;
}
if (fox->name() != "fox") {
std::cout<<"Fox 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;
}

спросил(а) 2014-04-22T04:24:00+04:00 5 лет, 10 месяцев назад
1
Решение
50

В дополнение к тому, что деструктор не является виртуальным, вы возвращаете адрес локальной переменной. Это неопределенное поведение.

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

ответил(а) 2014-04-22T04:35:00+04:00 5 лет, 10 месяцев назад
35

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

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

ответил(а) 2014-04-22T04:34:00+04:00 5 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема