原文链接(点击原文链接获取更多学习干货):
fourteenth 联编、多态 – 布尔博客http://blog.bools.cn/archives/1700
1.联编
联编分为静态联编和动态联编, 静态联编就是说早绑定地址,属于静态
晚绑定地址属于动态
1.静态
class animal
{
public:
void speak()
{
cout << "小动物在说话" << endl;
}
};
class cat :public animal
{
public:
void speak()
{
cout << "猫在说话" << endl;
}
};
//调用spark函数的时候,speak的函数地址早就绑定好了,这属于早绑定,
//静态联编,就是说早就在编译是时候编译好了
void dospeak(animal & animal)
{
animal.speak();
}
//如果发生了继承,编译器允许发生类型转换
void test01()
{
cat cat;
dospeak(cat);
}
int main()
{
test01();
system("pause");
return 0;
}
例子中的speak函数,地址是绑定好了,属于早绑定,静态联编。
2.动态
动态联编,地址晚绑定,运行时再绑定。
class animal
{
public:
virtual void speak()
{
cout << "小动物在说话" << endl;
}
};
class cat :public animal
{
public:
void speak()
{
cout << "猫在说话" << endl;
}
};
//如果想要绑定猫的speak的话,就不能提前绑定函数地址,所以需要在运行的时候再去确定函数地址
//动态联编,写法只需要将父类的speak函数改为虚函数,改变函数结构,发生了多态
//多态的意思就是说父类的引用指向子类的对象
void dospeak(animal & animal)
{
animal.speak();
}
//如果发生了继承,编译器允许发生类型转换
void test01()
{
cat cat;
dospeak(cat);
}
如果想要绑定猫的speak的话,就不能提前绑定函数地址,所以需要在运行的时候再去确定函数地址
动态联编,写法只需要将父类的speak函数改为虚函数,改变函数结构,发生了多态
而多态的意思就是说,将父类的指针或者引用指向子类对象。
2.多态原理
当父类当中有了虚函数后,函数内部结构就发生了变化,内部多了一个vfprt的指针。
vfprt指针指向 virtuai function pointer虚函数表指针。
指向vftable函数表。
父类中结构vfptr 指向&animal::speak,而子类继承的时候也会继承指针,一开始的时候也会指向父类的这个表,而子类重新创建对象之后,就会将指针指向。
构造函数中,会将虚函数表指针,指向自己的虚函数表,
如果发生了重写,会替换掉原有的speak函数,换为&Cat::speak()函数。
class animal
{
public:
virtual void speak()
{
cout << "小动物在说话" << endl;
}
};
class cat :public animal
{
public:
virtual void speak()
{
cout << "猫在说话" << endl;
}
};