今天是: 2025年5月15日 星期四 返回首页 | 电脑培训学校简介 | 学校新闻 | 我要报名 | 就业体系 | 专业设计 | 联系我们
 
 
本站导航
· 校园文化 · 学校动态
· 学校公告 · 婚纱设计
· 平面设计 · 室内装潢
· 办公文秘 · 办公自动化
· 职称计算机
联系方式
邳州市天翼电脑培训学校
联系人:胡老师
手机:13092300677
Q Q:439524682
邮箱:439524682@qq.com
网址:http://www.pzdnpx.com
地址:邳州市镇北一路铁路立交桥向东10米天翼电脑培训学校

最新文章
· 学平面设计是一个全面
· 平面设计领域不断发展
· 平面设计是一门创意的
· 平面设计通常是团队合
· 对于数字平面设计而言
· 平面设计软件的使用
· 文字是设计中重要的表
· 色彩在平面设计中起着
当前位置:邳州电脑培训 --学校新闻
      
虚函数为内联是错误的

发布时间:2019-5-5  新闻类别:学校新闻 点击次数:457

我们曾经在讨论C++的时候,经常会问到:“虚函数能被声明为内联吗?”现在,我们几乎听不到这个问题了。现在听到的是:“你不应该使print成为内联的。声明一个虚函数为内联是错误的!”

    这种说法的两个主要的原因是(1)虚函数是在运行期决议而内联是一个编译期动作,所以,我们将虚函数声明为内联并得不到什么效果;(2)声明一个虚函数为内联导致了函数的多分拷贝,而且我们为一个不应该在任何时候内联的函数白白花费了存储空间。这样做很没脑子。

     我们先来看看个:许多情况下,虚拟函数都被静态地决议了——比如在派生类虚拟函数中调用基类的虚拟函数的时候。为什么这样做呢?封装。一个比较明显的例子是派生类析构函数调用链。所有的虚析构函数,除了最初触发这个析构链的虚析构函数,都被静态的决议了。如果不将基类的虚析构函数内联,我们无法从中获利[a]。这和不内联一个虚拟析构函数有什么不同吗?如果继承体系层次比较深并且有许多这样的类的实例要被销毁的话,答案是肯定的。

    再来看另外一个不用析构函数的例子,想象一下设计一个图书馆类。我们将MaterialLocation作为抽象类LibraryMaterial的一个成员。将它的print成员函数声明为一个纯虚函数,并且提供函数定义:它输出MaterialLocation。

class LibraryMaterial {

private:

MaterialLocation _loc; // shared data

// ...

public:

// declares pure virtual function

inline virtual void print( ostream& = cout ) = 0;

};

// we actually want to encapsulate the handling of the

// location of the material within a base class

// LibraryMaterial print() method - we just don’t want it

// invoked through the virtual interface. That is, it is

// only to be invoked within a derived class print() method

inline void 

LibraryMaterial::

print( ostream &os ) { os << _loc; }

接着,我们引入一个Book类,它的print函数输出Title, Author等等。在这之前,它调用基类的print函数(LibraryMaterial::print())来显示书本位置(MaterialLocation)。如下:

inline void 

Book::

print( ostream &os ) 

{

// ok, this is resolved statically, 

// and therefore is inline expanded ...

LibraryMaterial::print();

os << "title:" << _title

<< "author" << _author << endl;

}

AudioBook类,派生于Book类,并加入附加信息,比如旁述,音频格式等等。这些东西都用它的print函数输出。再这之前,我们需要调用Book::print()来显示前面的信息。

inline void 

AudioBook::

print( ostream &os ) 

{

// ok, this is resolved statically, 

// and therefore is inline expanded ...

Book::print();

os << "narrator:" << _narrator << endl;

}

这和虚析构函数调用链的例子一样,都只是最初调用的虚函数没有被静态决议,其它的都被原地展开。This unnamed hierarchical design pattern is significantly less effective if we never declare a virtual function to be inline.

那么对于第二个原因中代码膨胀的问题呢?我们来分析一下,如果我们写下:

LibraryMaterial *p = 

new AudioBook( "Mason & Dixon", 

"Thomas Pynchon", "Johnny Depp" );

// ...

p->print();

这个print实例是内联的吗?不,当然不是。这样不得不通过虚拟机制在运行期决议。这让print实例放弃了对它的内联声明了吗?也不是。这个调用转换为下面的形式(伪代码):

// Pseudo C++ Code

// Possible transformation of p->print()

( *p->_vptr[ 2 ] )( p );

where 2 represents the location of print within the associated virtual function table.因为调用print是通过函数指针_vptr[2]进行的,所以,编译器不能静态的决定这个调用地址,并且,这个函数也不能内联。

     当然,虚函数print的内联实体(definition)也必须在某个地方表现出来。 即是说,至少有一个函数实体是在virtual table调用的地址原地展开的。编译器是如何决定在何时展开这个函数实体呢?其中一个编译(implementaion)策略是当virtual table生成的同时,生成这个函数实体。这是说对于每一个派生类的virtual table都会生成一个函数实体。

      在一个可应用的类[b]中有多少vitrual table会被生成呢?呵呵,这是一个好问题。C++标准中对虚函数行为进行了规定,但是没有对函数实现进行规定。由于virtual table没有在C++标准中进行规定,很明显,究竟这个virtual table怎样生成,和究竟要生成多少个vitrual table也没有规定。多少个?当然,我们只要一个。Stroustrup的cfront编译器,很巧妙的处理了这些情况.( Stan and Andy Koenig described the algorithm in the March 1990 C++ Report article, "Optimizing Virtual Tables in C++ Release 2.0.")

       Moreover, the C++ Standard now requires that inline functions behave as though only one definition for an inline function exists in the program even though the function may be defined in different files。新的规则要求编译器只展开一个内联虚函数。如果一点被广泛采用的话,虚函数的内联导致的代码膨胀问题会消失。


 
发表评论】【打印新闻】【关闭窗口  
最新学校新闻
  · 平面设计是一门创意的艺术,设计师需要具备开放的思维和解决 [2024/6/6]
  · 平面设计通常是团队合作的一部分,因此具备良好的项目管理和 [2024/6/6]
  · 平面设计软件的使用 [2024/5/17]
  · 平面设计往往需要手绘草图或数字插图作为创作的基础 [2024/4/11]
  · 学平面设计首先需要对美学和设计原理有一定的了解 [2024/4/11]
  · 一个优秀的平面设计者需要不断的丰富自己的经历 [2024/3/9]
  · 立体构成重于组合与重建,创造新的整体造型,此手法也称为“ [2024/2/21]
  · 了解平面构成的原理,点,线,面与空间的构成是非常重要的 [2024/2/21]
  · 网页设计(web design)是根据企业希望向浏览者传 [2024/1/13]
  · 品牌/商标/标志是平面设计的重要组成部分 [2023/12/15]
  · 广告和海报是平面设计中具有宣传性的信息展现形式之一,通过 [2023/12/15]
  · 设计作品中物体的大小和比例被称为比例 [2023/11/23]
  · 对于想要展现给大家看的东西和想要表达的信息,都可以通过强 [2023/11/23]
  · 怎样才能让作品在视觉上有空间感?可运用阴影、透视、投影等 [2023/10/9]
  · 纹理可以激起用户对画面的情感波动,从凸起的砂砾到广阔无边 [2023/9/20]

 
 
电脑培训学校新闻中心 | 友情链接 | 网站地图 | 邳州电脑培训学校加入收藏 |邳州电脑培训学校设为首页
邳州电脑培训关键字: 邳州电脑培训 - 邳州电脑学校 - 邳州市天翼电脑培训学校 - 邳州电脑培训
Copyright &#169; 2011-2012 邳州市天翼电脑培训学校 All Rights Reserved.

你是第1245746位访客   建议使用1024×768以上分辨率,IE6.0以上浏览器    技术支持:
邳州慧网 银杏苗木 银杏树