我确定我错过了一些东西,但我真的无法在互联网上找到任何东西,为什么我的代码无法正常工作:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "string.h"
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
using namespace std;
class Animal {
private:
char *name;
protected:
enum { tele, empty } bendo;
public:
Animal() {};
Animal(const char *kname) : bendo(empty) {
name = new char[strlen(kname) + 1];
strcpy(name, kname);
}
const char *getname() { return name; }
virtual ~Animal() {
cout << "~" << name << endl;
delete[] name;
}
virtual void print(std::ostream& os) const {
os << "Animal.print" << std::endl;
}
};
class Monkey : public Animal {
protected:
static const char* SOUND;
public:
Monkey(const char *kname) : Animal(kname) { }
~Monkey() { cout << SOUND << SOUND << " "; }
virtual void print(std::ostream& os) const {
os << "Monkey.print" << std::endl;
}
};
const char* Monkey::SOUND = "Mak";
class Tiger : public Animal {
public:
Tiger(const char *kname) : Animal(kname) { }
virtual void print(std::ostream& os) const {
os << "Tiger.print" << std::endl;
}
};
class Cage{
Animal* animals;
unsigned int num;
public:
Cage(){};
~Cage();
void add(const Animal* a) {
Animal* tmp = new Animal[num + 1];
for (unsigned int i = 0; i < num; i++)
tmp[i] = animals[i];
tmp[num++] = *a;
cout << "param: ";
a->print(std::cout);
cout << "in cage: ";
tmp[num - 1].print(std::cout);
animals = tmp;
}
void print(std::ostream& os) {
for (unsigned int i = 0; i < num; i++){
animals[i].print(os);
}
}
};
int main() {
Animal *animal = new Animal("Animal");
Animal *cicus = new Tiger("Cicus");
Animal *csita = new Monkey("Csita");
Animal *tarzan = new Monkey("AIAIAIAI");
Cage* cage = new Cage;
cout << "add animal" << endl;
cage->add(animal);
cout << endl << "add cicus" << endl;
cage->add(cicus);
cout << endl << "add csita" << endl;
cage->add(csita);
cout << endl << "add tarzan" << endl;
cage->add(tarzan);
cout << endl << "cage->print(cout);" << endl;
cage->print(cout);
cin.get();
}
基本上,我想在这里做些什么:
如果我打电话给cage.print(...),我希望它可以打电话给所有动物&#39; print(...)方法(Monkey.print(...),Tiger.print(...)等),但它总是调用Animal.print(...)方法。对于此代码,这是输出:
add animal
param: Animal.print
in cage: Animal.print
add cicus
param: Tiger.print
in cage: Animal.print
add csita
param: Monkey.print
in cage: Animal.print
add tarzan
param: Monkey.print
in cage: Animal.print
cage->print(cout);
Animal.print
Animal.print
Animal.print
Animal.print
我在这里缺少什么?我做错了什么?
解
好吧,正如@rodrigo所说,我遇到了所谓的对象切片&#39;错误,为了避免这种情况,我不得不将Animal* animals
替换为Animal** animals
,因此我不存储Animal对象,而是存储Animal POINTERS 。我只是在这里复制代码的重要部分,所以它只显示了这个特定问题的解决方案,所以要小心,它会错过其他东西(比如内存处理!)。
class Cage{
Animal** animals; // We need to store pointers!
unsigned int num;
unsigned int max;
public:
Cage(){
num = 0;
max = 10;
animals = new Animal*[max];
};
void add(Animal* a) {
/* Here I just 'optimized' a bit,
but of course the best would be to use linked list. */
if (num == max) {
max*=2;
Animal** tmp = new Animal*[max];
for (unsigned int i = 0; i < num; i++) {
tmp[i] = animals[i];
}
animals = tmp;
}
animals[num++] = a;
}
}
答案 0 :(得分:1)
问题是你的animals
变量是Animal
的数组,你需要一个指针或引用才能有多态行为。
您无法构建引用数组,因此您需要一个指针数组:Animal **animals
。
当您将Monkey
复制到Animal
时,您实际执行的操作是复制对象的动物部分并丢失猴子部分。这被称为拼接,并且几乎要避免。
PS:您应该使用std::string
和std::vector
而不是管理自己的记忆。