简体   繁体   English

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

[英]Why my code giving me a stackdump error when I run it?

We are supposed to make classes of animals which inherit from classes of different types of animals, ie the Dog class will inherit from the Carnivore class which will inherit from the Mammal class. 我们应该使动物类继承自不同类型动物的类,即Dog类将从Carnivore类继承,而Carnivore类将从Mammal类继承。 I have tried using my classes in my own main function and they print out what they are supposed to say and their name but when I run my classes with my teacher's main file it tells me its dumping stack trace. 我尝试在自己的主函数中使用班级,它们打印出应该说的内容和名称,但是当我使用老师的主文件运行班级时,它会告诉我它的转储堆栈跟踪。

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

Some problems: 一些问题:

  • Lacking virtual destructor in base class. 基类中缺少虚拟析构函数。
  • Returning dangling pointers , pointers to local objects that have ceased to exist. 返回悬空指针 ,指向不再存在的本地对象的指针。
  • Exponential increase in memory consumption for foxes, as they bark. 狐狸吠叫时,其内存消耗呈指数增长。

In addition to the destructor not being virtual, you are returning the address of a local variable. 除了析构函数不是虚拟的之外,您还要返回局部变量的地址。 This is undefined behavior. 这是未定义的行为。

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?
    }
}

You make this same mistake for all the other derived classes. 对于所有其他派生类,您也会犯同样的错误。 Once that function returns, there is no more "D". 该函数返回后,将不再有“ D”。 It has gone up into a puff of smoke, and you're returning the address of this variable that no longer exists. 它变得一团雾气,您正在返回该变量不再存在的地址。

Either create a new Mammal ( return new Dog; ) or come up with a way to create a Dog and return one that isn't local (again, the issue isn't just with this class, but will all of our other classes). 创建一个新的Mammal( return new Dog; ),或者想出一种创建Dog并返回一个非本地的Dog的方法(同样,问题不仅仅与这个类有关,而是所有其他类都将涉及) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM