为什么我的代码在运行时会给我一个stackdump错误?

时间:2014-04-22 01:24:16

标签: c++ class inheritance stack-dump

我们应该制作继承自不同类型动物类别的动物类别,即Dog类将继承自将继承自哺乳动物类的Carnivore类。我已经尝试在我自己的主函数中使用我的类,并打印出他们应该说的内容和他们的名字但是当我用我的老师的主文件运行我的类时,它告诉我它的转储堆栈跟踪。

#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;
}

2 个答案:

答案 0 :(得分:0)

一些问题:

  • 在基类中缺少虚拟析构函数。
  • 返回悬空指针,指向已不复存在的本地对象。
  • 狐狸的记忆消耗呈指数增长,因为它们会吠叫。

答案 1 :(得分: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;),要么想出一种方法来创建一个狗并返回一个不是本地的狗(同样,问题不仅仅是这个类,而是全部我们的其他课程。)