首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取要调用的继承函数的函数

获取要调用的继承函数的函数
EN

Stack Overflow用户
提问于 2010-06-16 08:08:44
回答 3查看 176关注 0票数 3

假设我有一个基类Animal和一个包含Animal向量的Barn类,其中Cow类继承了这个基类,再假设Animal类有一个Cow重写的虚拟函数scream()

使用以下代码:

Animal.h

代码语言:javascript
复制
#ifndef _ANIMAL_H
#define _ANIMAL_H
#include <iostream>
using namespace std;

class Animal {
public:
    Animal() {};
    virtual void scream() {cout << "aaaAAAAAAAAAAGHHHHHHHHHH!!! ahhh..." << endl;}
};

#endif  /* _ANIMAL_H */

Cow.h

代码语言:javascript
复制
#ifndef _COW_H
#define _COW_H

#include "Animal.h"

class Cow: public Animal {
public:
    Cow() {}
    void scream() {cout << "MOOooooOOOOOOOO!!!" << endl;}
};

#endif  /* _COW_H */

Barn.h

代码语言:javascript
复制
#ifndef _BARN_H
#define _BARN_H

#include "Animal.h"
#include <vector>

class Barn {
    std::vector<Animal> animals;

public:
    Barn() {}
    void insertAnimal(Animal animal) {animals.push_back(animal);}
    void tortureAnimals() {
        for(int a = 0; a < animals.size(); a++)
            animals[a].scream();
    }
};

#endif  /* _BARN_H */

最后是main.cpp

代码语言:javascript
复制
#include <stdlib.h>
#include "Barn.h"
#include "Cow.h"
#include "Chicken.h"

/*
 * 
 */
int main(int argc, char** argv) {
    Barn barn;
    barn.insertAnimal(Cow());
    barn.tortureAnimals();
    return (EXIT_SUCCESS);
}

我得到以下输出:

代码语言:javascript
复制
aaaAAAAAAAAAAGHHHHHHHHHH!!! ahhh...

我应该如何编写代码来获得MOOooooOOOOOOOO!!! (以及其他继承Animal的类希望scream()成为的类)呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-16 08:16:56

稍微修改一下,存储指向动物的指针应该会有所帮助:

代码语言:javascript
复制
#ifndef _BARN_H
#define _BARN_H

#include "Animal.h"
#include <vector>

class Barn {
    std::vector<Animal *> animals;

public:
    Barn() {}
    void insertAnimal(Animal *animal) {animals.push_back(animal);}
    void tortureAnimals() {
        for(int a = 0; a < animals.size(); a++)
            animals[a]->scream();
    }
};


int main(int argc, char** argv) {
    Barn barn;
    barn.insertAnimal(new Cow());
    barn.tortureAnimals();

    // should clean up barn contents here...

    return (EXIT_SUCCESS);
}
票数 2
EN

Stack Overflow用户

发布于 2010-06-16 08:11:43

std::vector<Animal>只能包含Animal对象,不能包含Cow对象。

下面是当你说barn.insertAnimal(Cow());的时候会发生什么

Cow类型的临时对象是通过Cow().

  • The参数的求值创建的,animal是从该临时cow复制构造的,因为您选择按值传递它。此animal是临时奶牛的Animal-part的副本。这称为object-slicing.

  • The,向量中的下一个元素是从参数animal复制构造的。现在您已经有了一头母牛和两个额外的动物,但是您只需要一头母牛!

  • 参数animal被销毁,因为insertBarn返回。

  • 临时母牛被销毁,因为计算已经到达行尾的分号(更准确地说:完整表达式的计算已经完成)。

这里的教训是什么?不要按值传递动物,也不要按值存储动物。运行时多态性需要一定程度的间接性。您可能需要一个std::vector<Animal*>std::vector<shared_ptr<Animal> >boost::ptr_vector<Animal>

票数 12
EN

Stack Overflow用户

发布于 2010-06-16 08:24:49

您正在进行按值传递,因此将把Cow转换为Animal

使用Animal *可以正常工作,但这会造成内存泄漏:

代码语言:javascript
复制
class Barn {
    std::vector<Animal *> animals;

    void insertAnimal(Animal *animal) {animals.push_back(animal);}

    void tortureAnimals() {
        for(int a = 0; a < animals.size(); a++)
            animals[a]->scream();
    }
};

int main(int argc, char** argv) {
    Barn barn;
    Cow *c = new Cow();
    barn.insertAnimal(c);
    barn.tortureAnimals();
    /* delete them here... */
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3049952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档