0

我们应该创建继承自不同类型动物类的动物类,即 Dog 类将继承自 Carnivore 类,而 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;
}
4

2 回答 2

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”了。它已经化为乌烟瘴气,而您正在返回这个不再存在的变量的地址。

要么创建一个新的 Mammal ( return new Dog;),要么想出一种方法来创建一个 Dog 并返回一个不是本地的(同样,问题不仅在于这个类,还在于我们所有的其他类)。

于 2014-04-22T01:35:31.827 回答
0

一些问题:

  • 基类中缺少虚拟析构函数。
  • 返回悬空指针,指向已不存在的本地对象的指针。
  • 狐狸在吠叫时内存消耗呈指数增长。
于 2014-04-22T01:34:42.193 回答