我们知道C++里 virtual函数可以用来实现多态。继承类可以实现自己的功能来覆盖基类。比如下面这段代码
#include<iostream> #include<string> using namespace std; class BaseA{ public: BaseA(string n):name(n){} string getName() const; virtual void showMyName() const; string name; }; class DerivedA:public BaseA{ public: DerivedA(string n):BaseA(n){} string getName() const; virtual void showMyName() const; }; string BaseA::getName() const { cout<<"base static"<<endl; return name; } void BaseA::showMyName() const { cout<<"base:"<<name<<endl; } string DerivedA::getName() const { cout<<"derived static"<<endl; return name; } void DerivedA::showMyName() const { cout<<"derived:"<<name<<endl; } int main() { DerivedA * derivedA = new DerivedA(string("abcd")); BaseA baseA = * derivedA; //会调用copy constructor函数 baseA.showMyName(); baseA.getName(); BaseA * pBaseA = derivedA; pBaseA->showMyName(); pBaseA->getName(); return 0; }
这段代码的输出:
base:abcd
base static
derived:abcd
base static
我们来解读一下:
BaseA baseA = * derivedA;
这里其实是构造了一个BaseA类,也就是构造了一个基类,虽然是右值是继承类。
但这里会调用BaseA的default copy assignment函数,构造一个BaseA的实例。
derivedA会被截断。
那么当然了
baseA.showMyName(); baseA.getName();
这俩行会调用BaseA的函数。
我们再看一下下面这行
BaseA * pBaseA = derivedA;
这里声明了一个BaseA的指针 然后把指针指向派生类 DerivedA的一个实例。
再看下面的代码
pBaseA->showMyName();
pBaseA->getName();
showMyName我们定义成了Virtual,也就是在内存里会有个函数指针,指向不同的实现。
对于derivedA来说,这个函数的指针当然是指向DerivedA的showMyName。
而pBaseA拿到的是derivedA的指针,那么当然调用的函数也会是DerivedA的实现函数。
这个就是所谓的动态绑定。
下面再看getName,相对于动态绑定函数,这是个静态函数,什么事静态函数呢,
就是这个函数会根据对象的静态类型来调用。比如pBaseA的静态类型是BaseA,
那么pBaseA所调用的就是BaseA的getName。