摘录 C++编程思想。
先看下面程序://vc9.0下运行的
#include"iostream"
using namespace std;
enum note{middleC,Csharp,Cflat };
class instrument{
public:
void play(note) const {
cout<<"instrument::paly"<<endl;
}
};
class wind:public instrument{
public:
void play(note) const{ cout<<" wind::play "<<endl; }
};
void tune(instrument & i)
{
i.play(middleC);
}
int main()
{
wind flute;
tune (flute);
}
输出的是基类的:instrument::paly
这称为早捆绑,就是运行之前,就把void play(note)和基类绑好了;为了这对于C++的多态性没有任何意义,举个例子说:
鸟是基类:包括羽毛,一对翅膀、、、、
现在要定义啄木鸟和乌鸦,它们的羽毛的颜色不一样,翅膀的大小也不一样,我们就要实现啄木鸟和乌鸦这两个新的类里的羽毛和翅膀这两个成员随其类的不同为不同,而不能像上例那样还去访问基类的成员。这就引入了晚捆绑(就是很多书上说的 到要用 才运行),也就是引入虚函数。
改上例如下:
#include"iostream"
using namespace std;
enum note{middleC,Csharp,Cflat };
class instrument{
public:
virtual void play(note) const {
cout<<"instrument::paly"<<endl;
}
};
class wind:public instrument{
public:
void play(note) const{ cout<<" wind::play "<<endl; }
};
void tune(instrument & i)
{
i.play(middleC);
}
int main()
{
wind flute;
tune (flute);
}
多加入一个virtual 后结果为:wind::play 从而实现 了晚捆绑,为多态的实现立下汗马功劳。
上面是一层继承,对于多层继承,先看如下例子:
#include"iostream"
using namespace std;
class base{
public:
virtual int f() const{return 1;}
virtual int fun() const {return 11;}
};
class derived:public base{
public:
int f() const{return 2;}
int fun()const{return 21;}
};
class derived1:public derived{
public:int f() const{return 3;}
int fun() const{return 31;}
};
int main()
{derived1 d;
base *b=&d;
cout<<b->fun();
}
结果是:31.
如删除 int fun() const{return 31;}结果是 21
如再删除int fun()const{return 21;}结果是11
如再删除virtual int fun() const {return 11;} 报错了
这说明了:一个对象不可能出现绑定不到虚函数的情况,若对象的类没有,则自动向上映射,知道找到虚函数,没找到就报错。
编译器为新类创建一个新表VTABLE,把函数地址放里面,对于没有重建的虚函数的地址使用其上层的虚函数的地址;
达到使用基类的指针控制派生类的对象的目的。
注意事项:对于构造函数里的虚函数,它调用的是本地的虚函数。与其他函数不一样哦
构造函数不能是虚函数,而析构可以,特别注意的是,析构函数里的虚函数也是本本虚函数哦
虚拟函数当然也可以当成普通函数那样静态调用 只是加域操作符::就可以了