当前位置: 首页 > wzjs >正文

短视频投放方案seo分析报告怎么写

短视频投放方案,seo分析报告怎么写,如何在百度上打广告,宝鸡市建设工程信息网virtual function 的一般实现模型是: 每一个 class 有一个virtual table,内含该 class 之中有作用的 virtual function 的地址; 然后每个 object有一个 vptr,指向 virtual table 的所在。 问题一:怎么判断对象有多态特性 识别一…

virtual function 的一般实现模型是:

每一个 class 有一个virtual table,内含该 class 之中有作用的 virtual function 的地址;
然后每个 object有一个 vptr,指向 virtual table 的所在。

问题一:怎么判断对象有多态特性

识别一个 class 是否支持多态,唯一适当的方法就是看看它是否有任何 virtual function。只要 class 拥有一个 virtual function,在编译时期进行改写,并在它执行期进行动态链接。(也叫做“执行期类型判断法(runtime type resolution)”)

ptr->z();

问题二:需要存储什么额外信息

回到ptr->z(),我们需要知道以下信息才能帮助我们在执行期找到正确的实体:

  • ptr 所指对象的真实类型。这可使我们选择正确的 z() 实体;

  • z()实体位置,以便我能够调用它

在实现上,首先我可以在每一个多态的 class object 身上增加两个 members:

  1. 一个字符串或数字,表示 class 的类型;

  2. 一个指针,指向某表格,表格中带有程序的 virtual functions 的执行期地址。

表格中的 virtual functions 地址如何被建构起来? 在C++中,virtual functions(可经由其 class object 被调用)可以在编译时期获知,此外,这一组地址是固定不变的,执行期不可能新增或替换之。由于程序执行时,表格的大小和内容都不会改变,所以其建构和存取皆可以由编译器完全掌握,不需要执行期的任何介入。

然而,执行期备妥那些函数地址,只是解答的一半而已。另一半解答是找到那些地址。以下两个步骤可以完成这项任务:

  • 为了找到表格,每一个 class object 被安插上一个由编译器内部产生的指针,指向该表格

  • 为了找到函数地址,每一个 virtual function 被指派一个表格索引值

这些工作都由编译器完成。执行期要做的,只是在特定的 virtual table slot(记录着 virtual function 的地址)中激活 virtual function。

单一继承下的的Virtual Functions

一个 class 只会有一个 virtual table。每一个 table 内含其对应的 class object中所有active virtual functions 函数实体的地址。这些 active virtual functions 包括:

  • pure virtual called函数实体。

  • 继承自 base class 的函数实体。derived class 不改写virtual function 时会出现的情况

  • 本 class 所定义的函数实体。会改写 (overriding) base class virtual function 函数实体。

每一个 virtual function 都被指派一个固定的索引值,这个索引在整个继承体系中保持与特定的 virtual function 的关联。例如在我们的 Point class 体系中:

class Point {
public:virtual ~Point();virtual Point& mult( float ) = 0;// ..其它操作float x() const { return  x; }virtual float y() const { return 0; }virtual float z() const { return 0; }
.. ...
protected:Point( float x = 0.0 );float x;
}

virtual destructor 被赋 slot1,而 mult被赋值 slot2,此例并没有 mult()的函数定义(译注:为它是一个 pure virtualfunction),所以pure virtual called 的函数地址会被放在 slot2 中如果该函数意外地被调用,通常的操作是结束掉这个程序。

y0 被赋值 slot3 而 z0 被赋值 slot4。x的 slot 是多少?答案是没有,因为x0并非 virtual function。图4-1表示Point 的内存布局和其 virtual table。

class Point2d : public Point {
public:Point2d( float x = 0.0,float y = 0.0 ): Point( x ),_y( y.) { }~Point2d();// 改写 base class virtual functionsPoint2ds mult( float );float y() const { return  y; )//其它操作 0....
protected;float y;
}

派生类构建虚表时可能会出现的情况:

  1. 继承 。将base 中的函数实体地址会被拷贝到 derived class 的 virtual table 相对应的 slot 之中;

  2. 改写。使用自己的函数实体(override),这表示它自己的函数实体地址必须放在对应的 slot 之中

  3. 新增。声明新的 virtual function,这时候 virtual table 的尺寸会增大一个 slot,而新的函数实体地址会被放进该 slot 之中。

Point2d的 virtual table 在 slot 1 中指出 destructor,而在 slot 2中指出mult0(取代 pure virtual function)。它自己的y0函数实体地址放在 slot3,继承自 Point的 z0函数实体地址则放在 slot4。

class Point3d : public Point2d {
public:Point3d( float x= 0.0,float y=0.0,float z= 0.0): Point2d( x,y ),_z( z ) { }~Point3d();// 改写 base class virtual functionsPoint3d& mult( float );float z() const { return _z;} //..····其它操作
protected:float _z;
}

其 virtual table 中的 slot 1 放置 Point3d 的 destructor,slot 2放置Point3d::mult0函数地址。slot3 放置继承自 Point2d 的 y0函数地址,slot4 放置自己的z0函数地址。图4.1 显示 Point3d 的对象布局和其 virtualtable。

现在,如果我有这样的式子:

ptr->z();

那么,我如何有足够的知识在编译时期设定 virtual function 的调用呢?

  • 虽然不知道 ptr 所指对象的真正类型,但可以经由 ptr存取到该对象的 virtual table。

  • 虽然我不知道哪一个 z()函数实体会被调用,但 每一个 z() 函数地址都被放在 slot 4。

这些信息使得编译器可以将该调用转化为:

(*ptr->vptr[ 4 ])( ptr );

在这个转化中,vptr 示编译器所安的指针,指向 virtual table;4 表示z)被赋值的 slot 编号(关联到 Point 体系的 virtual table)唯一一个在执行期才能知道的东西是:slot4 所指的到底是哪一个 z函数实体?

在一个单一继承体系中,virtual function 机制的行为十分良好,不但有效率而且很容易塑造出模型来。但是在多重继承和虚拟继承之中,对 virtualfunctions 的支持就没有那么美好了。

多重继承下的Virtual Functions

// class 体系,用来描述多重继承(MI)情况下支持 virtual function 时的复杂度
class Base1 (
public:Base1();virtual ~Base1();virtual void speakClearly();virtual Base1 *clone() const;
protected:float data_Base1;
};class Base2 (
public:Base2();virtual ~Base2();virtual void mumble();virtual Base2 *clone() const;
protected:float data_Base2;
};class Derived : public Base1, public Base2 {
public:Derived();virtual ~Derived();virtual Derived *clone() const;
protected:float data_Derived;
};

Derived 支持 virtual functions的困难度,统统落在 Base2 subobject 身上。有三个问题需要解决:

(1)通过一个“指向第二个 base class”的指针,调用 derived class virtual function。例如virtual destructor,

Base2 *ptr = new Derived;
// 调用 Derived::~Derived
// ptr 必须被向后调整 sizeof( Base1 )个 bytes
delete ptr;

从图4-2之中,你可以看到这个调用操作的重点:ptr 指向 Derived 对象中的Base2 subobiect;为了能够正确执行,ptr 必须调整指 Derived 对象的起始处。

(2) 通过一个“指向 derived class”的指针,调用第二个 base class 中一个继承而来的 virtual function。例如,被继承下来的 Base2::mumble:

Derived *pder = new Derived;
// 调用 Base2::mumble()
// pier 必须被向前调整 sizeof( Basel ) 个 bytes
pder->muble();

在此情况下,derived class指针必须再次调整,以指向第二个 base subobject。

(3)允许一个 virtual function 的返回值类型有所变化,可能是 base type ,也可能是 publicly derived type。例如, Derive::clone函数。它的 Derived 版本传回一个Derived class 指针,默默地改写了它的两个 base class 函数实体。当我们通过“指向第二个 baseclass”的指针来调用 clone时,this 指针的 offset 问题于是诞生:

Base2 *pbl = new Derived
// 调用 Derived* Derived::clone()// 返回值必须被调整,以指向 Base2 subobject
Base2 *pb2 = pb1->clone();

当进行 pb1->clone()时,pb1 会被调整指 Derived 对象的起始地址,于是clone的 Derived 版会被调用;它会传回一个指针,指向一个新的 Derived 对象;该对象的地址在被指定给 pb2 之前,必须先经过调整,以指向 Base2subobiect。

问题一:

首先,我把一个从 heap 中配置而得的 Derived 对象的地址,指定给一个Base2指针:

Base2 *pbase2 = new Derived;

新的 Derived 对象的地址必须调整,以指向其 Base2 subobiect。编译时期会产生以下的码:

// 转移以支持第二个 base class
Derived *temp= new Derived;
Base2 *pbase2= temp ? temp + sizeof( Basel ) : 0;

一般规则是,经由指向“第二或后继之 base class的指针(或 reference)来调用 derived class virtual function。译注,就像本例的,

Base2 *pbase2 = new Derived;
delete pbase2; // invoke derived class's destructor (virtual)

该调用操作所连带的“必要的 this 指针调整”操作,必须在执行期完成。也就是说,offset 的大小,以及把 offset 加到 this 指针上头的那一小段程序代码必须由编译器在某个地方插入。

解决方式一 Bjarne :

将 virtual table 加大,使它容纳此处所需的 this 指针。每一个 virtual table slot,不再只是一个指针,而是一个聚合体,内含可能的 offset 以及地址。于是 virtual function 的调用。其中faddr内含 virtual function 地址,offset 内含 this 指针调整值

操作由:
*pbase2->vptr[1])( pbase2 );
改变为:
( *pbase2->vptr[1].faddr )( pbase2 + pbase2->vptr[1].offset );

这个做法的缺点是,它相当于连带处罚了所有的 virtual function 调用操作不管它们是否需要 offset 的调整。我所谓的处罚,包括 offset 的额外存取及其加法,以及每一个 virtual table slot 的大小改变。

解决方式二 Thunk:

引入一小段 assebly 码,用来(1)以适当的offset 值调整 this 指针,(2)跳到 virtual function 去。例如,经由一个 Base? 指针调用 Derived destructor,其相关的 thunk 可能看起来是这个样子:

//虚拟 C++码
pbase2 dtor thunk:this += sizeof( basel );Derived::~Derived( this );

此技术允许 virtual table slot 继续内含一个简单的指针,因此多重继承不需要任何空间上的额外负担。Slots 中的地址可以直接指向 virtual function,也可以指向一个相关的 thunk (如果需要调整 this 指针的话)。于是,对于那些不需要整 this 指针的 virtual function而言,也就不需承载效率上的额外负担。

解决了单个vtable内的存取效率,但是在多个vtable的动态链接上,仍然存在问题。

例如,同一函数在 virtual table 中可能需要多笔对应的 slots。

Basel *pbasel = new Derived;
Base2 *pbase2 = new Derived;
delete pbasel;
delete pbase2;

虽然两个 delete 操作导致相同的 Derived destructor,但它们需要两个不同的virtual table slots:

在多重继承之下,一个 derived class 内含 n-1 个额外的 virtual tables,n 表示其上一层 base classes 的数目(因此单一继承将不会有额外的 virtual tables对于本例之 Derived 而言,会有两个 vitualtables 被编译器产生出来:

1.一个主要实体,与Base1(最左端 base class)共享

2.一个次要实体,与 Base2(第二个 base class)有关

针对每一个 virtualtables,Derived 对象中有对应的 ptr。图4-2说明了这点。vptrs将在 constructor(s)中被设立初值(经由编译器所产生出来的码)。

Sun 编译器将多个 virtual tables 合并为一个。指向次要表格的指针,可由主要表格名称加上一个 offset 获得在这样的策略下,每一个 class 只有一个具名的 virtual table。

上述三种情况,详见P166

虚拟继承下的virtual function

没有具体的讨论

class Point2d {
public:Point2d( float = 0.0, float = 0.0 );virtual ~Point2d();virtual void mumble();virtual float z();
protected;float _x,_y;
}class Point3d : public virtual  Point2d {
public:Point3d( float = 0.0, float = 0.0, float = 0.0 );~Point3d();float z();
protected;float _z;
);

函数的效能

参考: https://zhuanlan.zhihu.com/p/657688995

Part 1: All About Virtual Keyword in C++: How Does Virtual Function Works Internally? | Vishal Chovatiya

http://www.dtcms.com/wzjs/295104.html

相关文章:

  • 网页制作网站发布教学设计高端网站建设公司排行
  • asp程序制作网站网站建设网络营销
  • 做网站建网站个人开发app去哪里接广告
  • 专做sm的网站百度经验官网入口
  • 搜索引擎怎么收录网站潍坊网站开发公司
  • 买高端品牌网站seo网站优化是什么
  • 华夏名网网站管理助手手机百度账号登录入口
  • 苏州比较好的建筑公司seo排名点击器
  • 网站的备案要求吗新手怎么做销售
  • 做论坛推广的网站西安关键词seo公司
  • 营销网站建站开发免费访问国外网站的app
  • 上海市网站网络seo推广培训
  • 哈尔滨建站系统营销培训视频课程免费
  • 广州网站建设哪里买互联网营销师培训教材
  • 网站开发切换电脑版与手机版seo外链推广工具下载
  • 备案上个人网站和企业网站的区别网站优化排名推荐
  • 北京建筑公司有哪些seo网站推广全程实例
  • 网站返回首页按钮刷赞业务推广网站
  • 微餐饮建站费用网络服务器有哪些
  • php网站搭建教程自助发外链网站
  • wordpress建站多少钱网站关键词快速排名服务
  • 无锡崇安网站建设站长统计是什么意思
  • 网站在哪里建立营销型网站建设专家
  • 1000个简单的小手工湖北百度seo排名
  • 有哪些网站做返利模式网络优化工程师证书
  • 陕西营销型网站建设软文代发价格
  • 购物网站优惠券怎么做友情链接网
  • 怎么做电视台网站培训计划方案模板
  • 影响网站速度因素 dns关键词排名优化提升培训
  • 政府网站建设方向品牌推广服务