静态关联
- 调用时机:在编译期确定。
- 确定调用函数依据:根据函数参数的静态类型(即声明时的类型)来确定调用哪个函数。编译器在编译时就知道要调用的具体函数版本。
- 举例:
class Animal {
public:
void makeSound() {
std::cout << "Animal makes a sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
Animal a;
a.makeSound(); // 静态关联,编译期确定调用Animal::makeSound
Dog d;
d.makeSound(); // 静态关联,编译期确定调用Dog::makeSound
Animal* ptr = &d;
ptr->makeSound(); // 静态关联,因为ptr静态类型是Animal*,所以调用Animal::makeSound
return 0;
}
动态关联
- 调用时机:在运行期确定。
- 确定调用函数依据:根据对象的实际类型(即运行时对象的真实类型)来确定调用哪个函数。这依赖于虚函数表(vtable)和虚函数指针(vptr)。当通过基类指针或引用调用虚函数时,运行时系统会根据对象的vptr找到对应的vtable,从而确定要调用的实际函数。
- 举例:
class Animal {
public:
virtual void makeSound() {
std::cout << "Animal makes a sound" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Dog barks" << std::endl;
}
};
int main() {
Animal* ptr = new Dog();
ptr->makeSound(); // 动态关联,运行时根据ptr指向的实际对象类型Dog,调用Dog::makeSound
delete ptr;
return 0;
}