虚函数
多态(继承关系的多个类型)通过虚函数实现。
关键字virtual告诉编译器不应当完成早绑定,而是自动实现晚绑定/运行时绑定所必须的所有机制。动态绑定只有当通过指针或者引用调用虚函数时才会发生。编译器为每个包含虚函数的类创建一个表,放置特定类的虚函数地址,秘密设置一个指针,指向上述表。做多态调用时,编译器静态获取vptr,并在表中查找函数地址的代码,这样就能调用正确的函数使晚绑定发生。
补充:析构函数可以是虚函数,所有的派生类的析构函数都将自动变为virtual型,不会出现由于析构函数未被调用而导致的内存泄漏(虚函数采用虚调用的办法,可以在只有部分消息的情况下工作,适合知道接口不知道准确类型的函数);但构造函数不可以是虚函数,创建对象,势必要知道对象的准确类型。构造函数可以重载,析构函数不能重载(构造函数根据参数不同实现重载,析构函数没有参数)。
根据下面具体的题目分析:
struct A{
void foo(){printf("foo");}
virtual void bar(){printf("bar");}
A(){bar();}
};
struct B:A{
void foo(){printf("b_foo");}
void bar(){printf("b_bar");}
};
A *p=new B;
p->foo();
p->bar();
输出为:
A *p=newB;// A类指针指向一个实例化对象B, B类继承A类,先调用父类的无参构造函数,bar()输出bar,B类没有自己显示定义的构造函数。
p->foo();//执行B类里的foo()函数,因为foo不是虚函数,所以直接调用父类的foo函数,输出foo
p->bar();//执行B类的bar()函数, 该函数为虚函数,调用子类的实现,输出b_bar
输出:barfoob_bar