设为首页 加入收藏

TOP

C++如何处理内联虚函数
2014-11-23 20:12:44 】 浏览:232
Tags:如何 处理 内联 函数

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


  虚函数有多态性,意味着派生的类能实现相同的函数,但功能却不同。假设 GetVal 被声明为虚函数,并且你有第二个 以不同方法实现的类 CFoo2:    class CFoo2 : public CFoo {
    public:
    // virtual in base class too!
    virtual int CFoo2::GetVal() {return someOtherVal;}
    };  如果 pFoo是一个 CFoo 或 CFoo2 指针,那么,无论 pFoo 指向哪个类 CFoo 或 CFoo2,成员函数 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.SetVal(17)
    int y = x.GetVal()   编译器知道x是 CFoo,而不是CFoo2,因为这个堆对象是被显式声明的。x肯定不会是CFoo2。所以展开 SetVal/GetVal 内联是安全的。如果要写更多的复杂代码:  CFoo x;
  CFoo* pfoo=&x;
  pfoo->SetVal(17);
  int y = pfoo->GetVal();
  ...
  CFoo2 x2;
  pfoo = &x2;
  pfoo->SetVal(17); //etc.编译器知道 pfoo 第一次指向x,第二次指向x2,所以展开虚拟函数也是安全的。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++计算四则表达式的模板 下一篇在预先定义的内存位置构造一个对象

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目