具有继承的编译器行为

时间:2017-10-31 10:09:18

标签: c++ inheritance

当我在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的方法?

1 个答案:

答案 0 :(得分:2)

根据您的代码,animal->talk()将始终致电Animal::talk()。因为animalAnimal *Animal::talk()不是虚拟的。

现在,如果您将Animal::talk()设为虚拟,animal->talk()将会调用Dog::talk()。通常,这是通过在animal的vtable上查看运行时来查看对象的实际类型,然后调用最合适的talk()函数来完成的。但由于上面有Animal *animal = new Dog(),编译器可以选择通过跳过vtable查找来优化调用,并直接调用Dog::talk(),因为类型在编译时已知。