我对C ++数组的理解是,您不能分配抽象类对象的数组,因为C ++不知道如何为尚未确定的类类型分配内存。
我整理了一个让我有些困惑的小例子,所以想再问一下
#include <iostream>
class Animal {
public:
virtual void hello() {}
};
class Dog : public Animal {
public:
void hello() { std::cout << "woof!" << std::endl; }
};
class Cat : public Animal {
public:
void hello() { std::cout << "meow" << std::endl; }
};
int main() {
Dog d;
d.hello(); // prints "woof!"
Cat c;
c.hello(); // prints "meow"
// how are we allowed to create an array of abstract class?
// doesn't c++ need to know how to allocate memory for any abstract
// class in order to do this?
Animal creatures[5];
creatures[0] = d;
creatures[1] = c;
creatures[4] = d;
// prints "6Animal"
std::cout << typeid(creatures[0]).name() << std::endl;
// this appears to call the Animal hello(), which does nothing
creatures[1].hello();
}
问题
谢谢!
Animal
不是抽象的。它不包含纯虚拟成员函数。将c
和d
分配给creatures
的元素时,即为slicing。
如果是,则将Animal::hello
声明为纯虚拟的,即
class Animal {
public:
virtual void hello() = 0;
};
[Animal creatures[5]
将是fail to compile,因为Animal
现在是抽象的。
根据您的第二个问题,C ++中的运行时多态仅适用于引用和指针。如果您熟悉Java或Python之类的语言,乍一看可能有点奇怪,但是请记住,在这些语言中,类类型的所有变量都是指针(或者仍然是类似指针的东西)。
在C ++中,Animal creatures[5]
将被放置在内存中,如下所示:
creatures
+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+
在Java中,Animal[] creatures = new Animal[5];
将这样布置在内存中:
+-----------+ +---+---+---+---+---+
| creatures +-->+ 0 | 1 | 2 | 3 | 4 |
+-----------+ +-+-+-+-+-+-+-+-+-+-+
| | | | |
+--------+ | | | | | +--------+
| Object +<+ | | | +>+ Object |
+--------+ | | | +--------+
v | v
+------+-+ | ++-------+
| Object | | | Object |
+--------+ | +--------+
v
+----+---+
| Object |
+--------+
[C ++数组没有像Java或Python这样的直接类似物