当我在C ++中使用up-casting时,我对编译器行为有疑问。 例如,我有这个简单的代码:
class Animal {
public:
Animal() {}
void talk() {
std::cout << "I am an animal" << std::endl;
}
};
class Dog :public Animal {
public:
Dog(){}
void talk() {
std::cout << "I am a dog" << std::endl;
}
void eat() {
std::cout << "eating" << std::endl;
}
};
int main()
{
Animal* animal = new Dog();
animal->talk();//Output is "I am an animal"
//animal->eat();//Compilation error.
return 0;
}
我的问题是,当我运行它时编译器首先出现在哪里?它是否在Animal类中查找方法,然后因为我没有使用virtual调用Animal的talk()方法,或者它是否首先检查该方法是否存在于Dog类中,并且需要Animal的方法?
答案 0 :(得分:2)
根据您的代码,animal->talk()
将始终致电Animal::talk()
。因为animal
是Animal *
而Animal::talk()
不是虚拟的。
现在,如果您将Animal::talk()
设为虚拟,animal->talk()
将会调用Dog::talk()
。通常,这是通过在animal
的vtable上查看运行时来查看对象的实际类型,然后调用最合适的talk()
函数来完成的。但由于上面有Animal *animal = new Dog()
,编译器可以选择通过跳过vtable查找来优化调用,并直接调用Dog::talk()
,因为类型在编译时已知。