C++如何处理内联虚函数

C++如何处理内联虚函数,第1张

C++如何处理内联虚函数,第2张

当一个函数是内联虚函数时,会发生代码替换或者虚表调用吗?为了弄清楚内联函数和虚函数,让我们分别考虑它们。通常,内联函数是扩展的。class CFoo {
private:
int val;
public:
int GetVal(){ return val;}
int SetVal(int v){ return val = v;}
};这里,如果使用下面的代码:CFoo x;
x . set val(17);
int y = x . GetVal();那么编译器生成的目标代码就会和下面的代码片段一样:CFoo x;
x . val = 17;
int y = x . val;当然不能这么做,因为val是私有变量。内联函数的好处就是不用函数调用就能隐藏数据,仅此而已。

函数多态性是指派生类可以实现相同的功能,但功能不同。假设GetVal被声明为虚函数,并且您在基类中也有第二个类cfoo 2:class cfoo 2:public cfoo {
public:
/virtual!
virtual int cfoo 2::GetVal(){ return someOtherVal;}
};如果pFoo是CFoo或CFoo2指针,那么无论CFoo或CFoo2 pfoo指向哪个类,都可以成功调用成员函数pFoo-> getval。

如果一个函数既是虚函数又是内联函数会怎么样?记住,有两种方法可以构建内联函数,

第一种是在函数定义中使用关键字inline,比如:inline CFoo::GetVal(){ return val;}二是在类的声明中写函数体,就像前面的CFoo2::GetVal一样。因此,如果类的声明中包含了虚函数体,比如:class cfoo {
public:
virtual int getval(){ return val;}
};编译器认为这个函数GetVal是内联的和虚拟的。那么,多态性和内联特性是如何同时起作用的呢?

编译器遵循的第一条规则是,无论发生什么,多态性必须发挥作用。如果有指向CFoo对象的指针,pFoo->GetVal保证会调用正确的函数。一般来说,这意味着函数GetVal将被实例化为非内联函数,并且有一个vtable(虚拟表)条目指向它们。但这不代表这个功能不能扩展!看下面的代码:CFoo x;
x . set val(17)
int y = x . getval()编译器知道x是CFoo,不是CFoo2,因为这个堆对象是显式声明的。x肯定不是CFoo2。因此,扩展SetVal/GetVal内联是安全的。如果想写更复杂的代码:CFoo x;
CFoo * pfoo = & x;
pfoo-> set val(17);
int y = pfoo-> GetVal();
...
cfoo 2 x2;
pfoo = & x2;
pfoo-> set val(17);//等等。编译器知道pfoo第一次指向X,第二次指向x2,所以扩展虚函数也是安全的。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++如何处理内联虚函数

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情