C++中“virtual”关键字在对象而不是指针上的行为
Behaviour of the `virtual` keyword in C++ on objects instead of pointers
我试图理解虚拟函数。
考虑以下代码,
#include <iostream>
#include <memory>
#include <vector>
class Animal
{
public:
virtual void eat()
{
std::cout << "I eat like a generic animal.n";
}
};
class Wolf : public Animal
{
public:
void eat()
{
std::cout << "I eat like a wolf!n";
}
};
int main()
{
Animal a;
Wolf w;
a.eat();
w.eat();
}
使用virtual
关键字,我得到输出
I eat like a generic animal.
I eat like a wolf!
正如它应该做的那样。
但如果我删除虚拟关键字,我仍然会得到相同的输出!来自我的对虚拟函数的初步理解,如果没有virtual
,我应该得到输出
I eat like a generic animal.
I eat like a generic animal.
我缺了什么初级的东西吗?
我在Linux 上使用g++编译器
Animal * a = new Animal();
Animal * w = new Wolf();
a->eat();
w->eat();
<...>
delete a;
delete w;
按照现在的方式,行为是正确的,因为这两个变量显然有不同的类型。
多态性通过识别实例实际引用的对象类型来工作。
在您的情况下,您的实际动物如下:
Animal a; //a is an animal.
Wolf w; //w is a wolf.
所以,您根本没有使用多态性
你需要做的更像这样:
//Create a couple animal pointers.
Animal* a;
Animal* b;
//Create an animal instance and have a point to it.
a = new Animal();
//Create a wolf instance and have b point to it.
b = new Wolf();
//Calls Animal::eat as a is an animal.
a->eat();
//Calls Wolf::eat as a is a wolf.
b->eat();
请注意,您可以使用指针或引用来实现多态性的使用
这就是为什么在处理类类型时,通常应该通过const引用传递对象。
//Will call Animal::eat or Wolf::eat depending on what animal was created as.
void foo(const Animal& animal) {
animal.eat();
}
//Will always call Animal::eat and never Wolf::eat since this isn't a reference or
//a pointer. Will also "slice" a Wolf object.
void foo(Animal animal) {
animal.eat();
}
请注意,切片意味着它将不分青红皂白地将一个派生程度更高的类(狼)变成该类(动物)的派生程度更低的副本,这可能会非常误导和出乎意料。
即使没有虚拟,它仍然是一个方法。虚拟关键字允许在以下情况下进行多态行为:
Animal* wolf = new Wolf; // I eat like a wolf! (as long as eating is virtual)
通过使用virtual关键字,您将告诉编译器根据派生类型在运行时选择要调用的适当实现。
相关文章:
- 为什么指针对象没有调用默认构造函数
- 如何访问双指针对象中的方法
- 如何使用智能指针对象执行成员函数指针
- 调用带有指针对象错误的指针变量
- 如何从模板类重载创建的指针对象上的运算符?
- C++指针对象的运算符重载
- 如何初始化数组指针对象
- 如何打印出唯一指针对象向量中的值(基于范围的循环)?C++
- C++指针对象差异
- 涉及继承,指针对象的交易以及何时进行的问题
- 表达式必须在C 中具有指针对象类型
- 下标需要数组或指针类型表达式必须具有指针对象类型
- 字符指针对象和相应的字符数组元素比较
- 如何在 c++ 中克隆为弱指针对象
- 指针对象使用CPP中的指针表达式进行比较
- Visual Studio中智能指针对象的自定义视图
- 使用指针 /对象 /模板参数正确构成
- 如果我确定只有一个线程一次处理指针/对象,则C/C 仍应使用同步
- 如何将值分配给指针对象 c++
- 更改智能指针对象,然后访问它