深度探索C++对象模型 Function语意学笔记

TMS320F28335使用IQmath库 简介 1.1 简介 德州仪器公司TMS320C280X系列的IQmath库为C/C++程序收集了高度优化和准确的数学函数库,并精确地在TMS320C280X芯片上将浮点算法转换成固定点算法的运算代码。这些函数被经常用在密集的实时计算且运行速度和精度又是至关重要的程序里。使用这些函数你能拥有比使用同等标准的ANSI C语言编写的代码更快的运行速度。此外提供可以使用的高精密功能的TI IQmath库明显缩短你DSP应用开发时间。 安装IQmath 2.1 IQmath的内容 TI IQmath库可以同 阅读详情

    为什么C++可以进行函数重载呢?因为C++对函数进行编译的时候,对函数进行了重命名。即函数名称+参数数目+参数类型=新的函数名称。

    对于虚拟成员函数,如果normalize()是一个虚拟成员函数,则以下的调用:

    ptr->normalize();

    将会被内部转化为: ( *ptr->vptr[1] )( ptr ); //第二个ptr表示this指针。

    类似的,如果magnitude()也是一个虚拟函数的话,它将被转换如下:

    register float mag = magnitude();  ->  register float mag = (*this->vptr[2])(this);

    如果明确地调用,将会比较有效率。如下:

    register float mag = Point3d::magnitude();

    如果magnitude()声明为inline函数会更有效率。

    如果是类的对象调用虚拟成员函数,编译器将会对待一般的非静态成员函数一样进行处理,故不支持多态

    如果Point3d::normalize()是一个静态成员函数,那么以下两个调用操作:

    obj.normalize(); -> normalize_7Point3dSFv();

    ptr->normalize(); -> normalize_7Point3dSFv();

    将被转换为一般的nonmember函数调用。

    静态成员函数的主要特性就是它没有this指针。

    一:它不能够直接存取class中的非静态成员。

    二:它不能够被声明为const,volatile 或 virtual。

    三:它不需要经由class object 才被调用----虽然大部分时候它是这样被调用的。因此对于

    &Point3d::object_count(); 会得到一个数值 unsigned int (*) (); 而不是 unsigned int ( Point3d::*) ();

    静态成员函数有一个意想不到的好处:就是成为一个callback函数。

    ( (Point3d*)0)->object_count(); 其中的object_count() 只是简单的传回_object_count这个静态数据成员。这个习惯的来源是C++在引入静态数据成员之前,C++要求所有的成员函数必须由类的对象来调用。因此希望”没有class object存在“的情况下,程序方法的一个解决之道是很奇特的把0转换成一个class指针,因而提供出一个this指针实体。

    object_count( (Point3d*) 0 );

    C++中,多态(polymorphism)表示”以一个public base class的指针(或reference),寻址出一个derived class object“的意思。

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

    一:这个class所定义的函数体。它会改写(overriding)一个可能存在的base class virtual function函数实体。

    二:继承自base class的函数实体。这是在derived class决定不改写virtual function时才会出现的情况。

    三:一个纯虚拟函数(就是没有定义的函数,如果纯虚拟函数被调用,通常的操作是结束掉这个程序)。

    

 

 

    因此,我有这样的式子: ptr->z(); 这个时候,编译器将调用转化为( *ptr->vptr[4])(ptr); 在一个单一继承体系中,virtual function机制的行为十分良好,不但有效率而且很容易塑造出模型来。但是在多重继承和虚拟继承之中,对virtual functions的支持就没有那么美好了。

     Base2 *pbase2 = new Derived; 将会转换为 Derived *temp = new Derived; Base2 *pbase2 = temp? temp+sizeof(Base1) : 0;

      

 

虚拟继承下的Virtual Functions

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;

};

    这个时候的虚拟单一继承并不像”非虚拟的单一继承“情况那样一致。

 

    我的建议是,不要在一个virtual base class 中声明非静态数据成员。如果这么做,你会距离复杂的深渊越来越近。

    我们知道,取一个非静态数据成员member的地址,得到的结果是这个member在class布局中的偏移再加1)。它需要绑定于某个class object的地址上,才能够存取。

    取一个非静态成员函数nonstatic member function的地址,如果该函数是nonvirtual,则得到的结果是它在内存中真正的地址。它也需要被绑定于某个class object的地址上,才能够通过它调用该函数。所有的nonstatic member functions都需要对象的地址(以参数this指出)。

    使用一个"member function"指针,如果并不用于virtual function, 多重继承,virtual base class等情况的话,并不会比使用一个"nonmember function指针”的成本更高。而virtual function 的出现,会使得"member function指针“更复杂化。

指向Virtual Member Functions的指针

    float (Point::*pmf)() = &Point::z;

    Point *ptr = new Point3d;

    pmf, 一个指向member function的指针,被设置为Point::z()(一个virtual function)的地址。ptr->z(), 被调用的是Point3d::z()。我们从pmf间接调用z()呢?(ptr->pmf)(); 调用的是Point3d.z()吗?答案是yes。问题时如何实现的呢?

    我们知道,对一个非静态数据成员取其地址,将获得该函数在内存中的地址,然而面对一个虚拟函数,其地址在编译时候是未知的,所能知道的仅是virtual function在其相关的virtual table中的索引值。也就是说,对一个virtual member function取其地址,所能获得的只是一个索引值。例如:

    class Point

    {

    public:

        virtual ~Point();

        float x();

        float y();

        virtual float z();

    };

    &Point::~Point = 1; 取&Point::x()的地址则是内存中的地址。通过pmf来调用z(),会被转化为一个编译时期的式子,一般形式如下所示:

    (*ptr->vptr[ (int)pmf ] ) (ptr);

Inline Functions

    一般而言,处理一个inline函数,有两个阶段:

    一:分析函数定义。如果函数因其复杂度,或因其建构问题,被判断不可成为inline,它会被转为一个static函数。

    二:真正的inline函数扩展操作是在调用的那一个点上。这会带来参数的求值操作(evaluation)以及临时性对象的管理。

    在inline函数的扩展进行处理时,大部分的编译器厂商似乎认为不值得在inline支持技术上做详细的讨论。我们只有进入到汇编代码中,才可以看到是否真正的实现了Inline。

    一般而言,inline函数中的每一个局部变量都必须被放在函数调用的一个封闭区段内,拥有一个独一无二的名字。Inline函数中的局部变量,再加上有副作用的参数,可能会导致大量临时性对象的产生。特别是如果它以单一表达式被扩展多次的话。如果一个Inline函数被调用多次的话,会产生大量的扩张码,使程序的大小暴涨。所以,我们需要小心的处理。

 

 

 

 

 

Q格式-TI的dsp的IQmath学习 接触DSP和无刷电机源码时,对于计算的要求比较高。对Q格式做一下了解,当然也解答了我以前的疑问。 1.什么是定点数? 2.印象中的dsp不是应该支持浮点数的运算么? 在看ST的变换源码时,本没了解什么是Q格式,不过当时的理解是将sin(theta)在0-90度的值[0-1]区间做了放大,即为0-32768。下一步计算完后再右移15位缩小。 事实也如此Q格式,就是将一个小数放大若干倍后,用整数来表示小数 位数系统 做为较为底层的c程序员,或者说计算机的常识,我们对于一个数如何在计算机中存储的。不管是什么类 阅读详情

相关推荐

dsp处理浮点数_DSP编程技巧---详解浮点运算的定点编程

我们使用的处理器一般情况下,要么直接支持硬件的浮点运算,比如某些带有FPU的器件,要么就只支持定点运算,此时对浮点数的处理需要通过编译器来完成。在支持硬件浮点处理的器件上,对浮点运算的编程最快捷的方法就是直接使用浮点类型,比如单精度的float来完成。但是在很多情况下,限于成本、物料等因素,可供我们使用的只有一个定点处理器时,直接使用float类型进行浮点类型的运算会使得编译器产生大量的代码来完成...

weixin_30240765的博客 3093

STM32 进阶教程 19 - IQmath数学库的使用

前言 STM32 M3 系列是不带浮点运算单元的,小数运算都是采用定点转浮点试式实现的,本节给大家介绍一个很好用的定点转浮点数学运算库,IQmath是德州仪器 (TI) 的一个高度优化的高精度数学函数集合,使 C/C++ 编程人员可以将浮点算法无缝植入定点代码中。这些例程通常用于计算密集型实时应用,最佳执行速度和高精确度是这些应用的关键。通过使用这些例程,您可以获得比使用标准 ANSIC 语言编...

张十三的博客 2万+

IQmath的使用方法

在F2812的ROM中,有3K×16位被保留用于存放数学公式表以及未来的开发。主要应用于高速度和高jīng度的实时计算,比同等程度的ANSIC C语言效率更高,同时可以节省用户更多的设计和调试时间。1、IQmath库为了应用IQmath,首先要从TI官方网站下载IQmath库,文档名称为SPRC087。我们主要应用库里面的:IQmath.cmd,IQmathLib.h,IQmath.lib。新建...

weixin_30572613的博客 685

深度探索C++对象模型》阅读笔记 第四章 Function语意学

Nonstatic Member Functions(非静态成员函数) C++的设计准则之一就是:nonstatic member function至少必须和一般的nonmember function有相同的效率。 名称的特殊处理(Name Mangling)一般而言,member的名称前面会被加上class名称,形成独一无二的命名。 Virtual Member Functions(虚拟成员函数) vptr表示由编译器产生的指针,指向virtual table。它被安插在每一个“声明有(或继承自)一个或

哇咔咔的博客 374

[读书笔记] - 《深度探索C++对象模型》第4章 Function语意学

1. Member的各种调用方式 C++支持三种类型的member functions: static、nonstatic和virtual,每一种类型被调用的方式都不相同。 1.1 Nonstatic Member Functions C++的设计准则之一就是:nonstatic member function至少必须和一般的nonmember function有相同的效率。下面是一个nonmember function的定义: float magnitude3d(const Point3d* _

浮生的博客 406

深度探索C++对象模型》 读书笔记:第四章 Function 语意学

4.1Member的各种调用方式 Nonstatic Member Functions(非静态成员函数) C++的设计准则之一就是:nonstatic member function 至少必须和一般的nonmember function有相同的效率 名称的特殊处理 一般而言,member的名称前面会被加上class的明后才能,形成独一无二的命名,也就是mangling手法。对于member...

junya_zhang的博客 383

深度探索C++对象模型》读书笔记第四章:Function语意学

C++中类的非静态成员函数和一般函数具有相同的效率,编译器内部会将成员函数转化为对等的普通函数实体,比如加上 this 指针。一般而言,编译器对函数会用 ”mangling“ 手法进行命名处理,这也是函数重载的支持手段。独立于 class object 之外的存取操作,在某个时候特别重要。比如说 static 成员函数,它的主要特性是没有 this 指针,因此差不多等同于非成员函数,所以它可以成为

FreeeLinux's blog 652

深度探索C++对象模型》读书笔记Function语意学

C++支持三种类型的成员函数:static、nonstatic、virtual   1、C++的设计准则中说:非静态成员函数至少必须和一般的非成员函数有相同的效率。这是如何做到的? C++中的member function实际上被转化为nonmember的形式。下面是转化的步骤: 1>    改写函数的原型,安插一个额外的参数(this指针)到member functi

冰枫的随笔 1316

深度探索C++对象模型》学习笔记

深度探索C++对象模型》学习笔记 最近学习了c++对象模型,做下笔记,方便日后查阅 第一章:关于对象 c++对象模型 在此模型中,成员变量被配置在每一个对象中,静态成员变量、成员函数和静态成员函数放置在对象之外,虚函数则以下两个步骤支持: 每个类产生一堆指向虚函数的指针放在表格之中,这个表格叫做虚函数表(vtal) 每个对象中被添加一个指针(vptr),指向相关的虚函数表,vptr的赋值和重置由每个类的构造函数、析构函数和拷贝赋值运算符自动完成。每个类所关联的type_info放在虚函数表的表头

QT练手小程序 459

深度探索C++对象模型学习笔记——Function语意学

C++支持三种类型的成员函数:静态,非静态、和虚函数 虚函数细节:每个class有一个virtual table,内含该class之中有作用的virtual function地址,然后每个object有一个vptr,指向virtual table的所在。对于虚函数ptr->z();的调用,需要知道如下两点:1.ptr所指对象的真实类型,可使选择正确的z()实体;2.z()实体位置 

hong201的专栏 652

深度探索C++对象模型读书笔记】【第4章】Function语意学

1、 C++支持三种类型的member functions,static、nonstatic和virtual,每一种类型被调用的方式都不相同。 2、C++的设计准则之一便是nonstatic member function至少必须和一般的nonmember function有相同的效率。编译器内部会将member函数实例转换为对等的nonmember函数实例,转换步骤为: a)  改写函数

ruan875417的专栏 551

深度探索C++对象模型》读书笔记——Function 语意学【for_wind】

Member的各种调用方式

for_wind的专栏 913

深度探索C++对象模型 学习笔记 第四章 Function语意学(1)

假设我们有一个 Point3d 指针和对象: 问题在于,当我们写下: 时,实际会发生什么?其中 Point3d::normalize() 的实现如下: 而 Point3d::magnitude() 的实现为: 答案是:我们尚不得而知。C++ 支持三类成员函数:静态、非静态和虚函数。三者的调用方式各不相同,这些差异正是下一节要讨论的主题(小测验一则:尽管我们无法断言 normalize() 和 magnitude() 究竟是虚函数还是非虚成员,但可以放心地将它们排除在静态函数之外,因为这两者(a)都

tus00000的博客 399

深度探索C++对象模型 学习笔记 第四章 Function语意学(2)

但总的来说,目前的链接器在执行这种清理时,并不会一并清除随调用生成的调试信息——这可以通过 UNIX 的 strip 命令(该命令会从可执行文件、目标文件、共享库中移除符号表、调试信息和重定位信息,从而显著减小文件的体积,好处在于可使得逆向分析更加困难,以及提升发布版本的加载速度并降低存储成本)来完成。显然,这种复杂度度量中给各项赋予的具体数值是存在争议的。不过请注意:如果一个内联函数在程序中被调用太多次,那么它的展开代码总量,可能会远远超出你从它的定义表面所看到的规模,从而引发意想不到的代码膨胀。

tus00000的博客 427

阿龙的学习笔记---《深度探索C++对象模型》读书笔记(四)--- Function语意学

各种调用方式 class中有三种function可以调用:static、non-static、virtual,是有差异的。 非静态成员函数:Nonstatic Member functions C++设计准则是:应该与非成员函数的开销一样。所以其实调用时,会转换为非成员函数的形式,会将object通过this指针的方式传入。成员变量的读取也会转换为this指针的操作。 转换之后可能会加上前文提到的NRV优化,以及名称的特殊处理(Name mangling)即重新按照一定的规则命名。 虚拟成员

阿龙的博客 167
上一篇: 深度探索C++对象模型 Data语意学笔记
下一篇: 很全的智力题答案-1
caianye
博客等级 码龄19年 82粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值