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

90
10

Мы должны делать классы животных, которые наследуются от классов разных типов животных, то есть класс 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 6 лет, 5 месяцев назад
1
Решение
58

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

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 6 лет, 5 месяцев назад
41

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

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

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

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