5.程序转换语意学

2024-09-05 13:20
文章标签 语意 程序转换

本文主要是介绍5.程序转换语意学,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.显示的初始化操作

2.参数的初始化

3.返回值的初始化

4.在使用者层面做优化

5.Copy Constructor要不要?


1.显示的初始化操作

已知有这样的定义:

X x0;

下面的三个定义,每一个都明显地以x0来初始化其class object;

void foo_bar()
{X x1(x0); //译注:定义了x1X x2 = x0; //译注:定义了x2X x3 = X(x0);//译注:定义了x3//...
}

必要的程序转化有两个阶段:
1)在C++中,“定义”是指“占用内存”的行为。上面的代码将会重写每一个定义,其中的初始化操作会被剥离。
2)Class 的copy constructor调用操作将会被安插进去。

举个例子,在明确上面的两种转换后,foo_bar()可能看起来像这样子:

//可能的程序转换
//C++伪代码
void foo_bar(){X x1;//译注:定义被重写,初始化操作被剥离X x2;//译注:定义被重写,初始化操作被剥离X x3;//译注:定义被重写,初始化操作被剥离//编译器安插X copy construction的调用操作x1.X::X(x0);x2.X::X(x0);x3.X::X(x0);//...
}

2.参数的初始化

把一个class object当作参数传给一个函数(或是作为一个函数的返回值),如下的代码要求局部的实例x0以memberwise的方式将xx当作初值。在编译器的实现技术上,有一种策略是导入临时性object,并调用copy constructor将它初始化,然后将此临时性object交给函数。

void foo(X x0);
X xx;
//...
foo(xx);

例如将前一段程序代码转换如下:

//C++伪代码
//编译器产生的临时对象
X __temp0;//编译器对copy constructor的调用
__temp0.X::X(xx);//重新改写函数调用操作,使用上述的临时对象
foo(__temp0);

然而这样做有个问题,问题在foo的声明上。foo()的声明必须被转换,形式参数必须从原来的一个class X object改变成一个class X reference,像这样子:

void foo(X &x0);

其中class X声明了一个destructor,它会在foo()函数完成之后被调用,对付那个临时性的object。

3.返回值的初始化

已知下面的这个函数定义:

X bar()
{X xx;// 处理 xx ...return xx;
}

你可能会问bar()的返回值如何从局部对象xx中拷贝过来?Stroustrup在cfont中的解决办法是一个双阶段转化:

首先加上一个额外参数,类型是class object的一个reference。这个参数用来放置被“copy constructed”而得的返回值。

然后在return 指令之前安插一个copy constructor的调用操作。

上述的代码转换,可能如下:

//函数转换
//以反映出copy constructor的应用
//C++伪代码
void bar(X &__result)
{X xx;//编译器所产生的default constructor调用操作xx.X::X();//......处理xx//编译器所产生的copy constructor调用操作__result.X::X(xx);return;
}

在举几个例子,例如: X xx = bar();将被转换成如下的两个指令语句。

X xx;
bar(xx);

如果程序声明了一个函数指针,像这样子:

X (*pf)();
pf = bar;

它也被转换成这样子。

void (*pf)(X &x);
pf = bar;

4.在使用者层面做优化

最先提出“程序员优化”的概念是Jonathan Shopiro,他定义了一个“计算用”的constructor。换句话说,程序员不再写:

X bar(const T &y,const T &z)
{X xx;//...以y和z来处理xxreturn xx;
}

那会要求xx被“memberwise”的拷贝到编译器产生的__result之中。Jonathan定义另外一个constructor,可以直接计算xx的值。

X bar(const T &y,const T &z)
{return X(y,z);
}

于是当bar()的定义被转换之后,效率会更加的高。

//C++伪代码
void 
bar(X &__result,const T &y,const T &z)
{__result.X::X(y,z);return;
}

__result被直接计算出来,而不是经过copy constructor拷贝得到的。

5.Copy Constructor要不要?

已知下面的3D坐标点类:

class Point3d
{
public:Point3d(float x,float y,float z);//...
private:float _x,_y,_z;
};

这个class的设计者需要提供一个explicit copy constructor吗?答案是no,三个坐标成员是以数值来存储的。bitwise copy既不会导致memory leak,也不会产address aliasing。它是最快速安全的。

实现copy constructor的最简单的方式是:

Point3d::Point3d(const Point3d &rhs)
{_x = rhs._x;_y = rhs._y;_z = rhs._z;
}

这没有问题,但使用C++ library的memcpy()会更有效率:

Point3d::Point3d(const Point3d &rhs)
{memcpy(this, &rhs, sizeof(Point3d));
}

然而不管使用memcpy()还是memset(),都只有在“class不含有任何由编译器产生的内部members”时才能有效的运行。如果Point3d class声明一个或一个以上的virtual functions,或内含一个virtual base class,那么使用上述的函数将会导致那些“被编译器产生的内部members”的初值改写。

如你所见,如果要正确使用memcpy()和memset(),则需要掌握某些C++ Object Model的语意学知识。

这篇关于5.程序转换语意学的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139077

相关文章

C++对象模型学习——Function语意学

2019独角兽企业重金招聘Python工程师标准>>>        如果有一个Point3d的指针和对象: Point3d obj;Point3d *ptr = &obj;        当这样做: obj.normalize();ptr->normalize();         时,会发生什么事?其中的Point3d::normalize()定义如下: Point3d Poin

IOS 基础媒体文件格式语法描述和语意(MP4文件格式分析实例)

一、基本对象 Box Boxes start with a header which gives both size and type.  在最前面Box 包含 size和type,size和type都是占4个字节。 The header permits compact or extended size (32or 64 bits) and compact or extende

H.264 NAL语法语意以及字节流的语法语意

(参考 ITU-T H.264 建议书 2005年3月 第四版 ) 一、H.264的产生背景和目的:      随着处理能力和存储容量价格的下降,网络所能支持的编码视频数据的多样化,以及视频编码技术的进步,对具有较高压缩效率,并且有更好的网络健壮性的视频压缩和表示的工业标准的需求非常迫切。      为此,ITU-T 视频编码专家组(VCEG)和 ISO/

#include_next的语意

#include_next的语意 继承和头文件 继承是对象或者文件通过拷贝其它对象或文件的内容,从而衍生出一个新的对象。对于C语言的头文件来说,继承就是一个头文件包含另一个头文件,然后更改(如更改一些宏的值)或增加一些内容。 如果衍生头文件和基础头文件(base header file)的文件名不同,处理方法很简单,只需在衍生头文件中包含基础头文件即可#include "basic"(base指

数据结构【八】- 递归【一】递归的本质/ 递归的宏观语意/ 写递归算法的基本原则/ 递归函数的“微观”解读

一。递归的本质             本质上,递归就是将原来的问题,转化为更小的同一问题。 二。递归的举例 更多链表问题搜索:LinkedListProblems.pdf (一)例子           用递归来写数组求和 (二)思路 1. 对一个数组求和就等于:将【数组总和】=【数组的第0个数】+【数组中从1索引到...n-1这个索引的和】。 这个时候,Sum(arr[1..

构造、析构、拷贝语意学

目录 一、构造1.1、"无继承"情况下的对象构造1.1.1、抽象数据类型1.1.2、为继承做准备 1.2、继承体系下的对象构造1.2.1、虚继承1.2.2、vptr初始化语意学 二、拷贝三、析构四、总结 一、构造 1.1、"无继承"情况下的对象构造 考虑下面代码: L1、L5、L6表现出三种不同的对象产生方式:global内存配置、local内存配置和heap内存配置。

构造函数语意学

目录 一、默认构造函数1.1、带有default constructor的成员类对象1.2、带有default constructor的基类1.3、带有一个虚函数的类1.4、带有一个虚基类的类1.5、小结1.5.1、两个误解 二、拷贝构造函数2.1、default memberwise initialization2.2、不展现bitwise copy semantics2.3、带有虚函数

Function语意学

目录 一、成员函数各种调用方式1.1、非静态成员函数1.1.1、转换函数1.1.2、转换调用1.1.3、名称的特殊处理1.1.3.1、数据成员1.1.3.2、成员函数 1.2、虚成员函数1.3、静态成员函数1.3.1、特性 二、虚成员函数2.1、单一继承下的虚函数2.1.1、必要的信息及其存放位置2.1.2、构建virtual table2.1.3、示例 2.2、多重继承下的虚函数2.2

国考省考行测:选词填空,逻辑填空,语境分析,语意辨析,刷题,

国考省考行测:选词填空,逻辑填空,语境分析 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能,附带行测和申论,而常规国考省考最重要的还是申论和行测,所以大家认真准备吧,我讲一起屡屡申论和行测的重要知识点 遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle,尤其sql要学,当然,像很多金融企业、安全机构啥的,他们必须要

图像语意分割训练Cityscapes数据集SegNet-ConvNet神经网络详解

前言:经过几个月的学习研究,在神经网络中训练多分类语意分割模型识别城市街景信息,终于在最近得到了理想中的实验结果。在我陷入对细节参数调整不当及诸多问题时,苦于没有一篇能够“面向新手编程”的博客。因而我在能够在解决一系列问题到达终点后总结这一路踩过的坑,希望对后来者有所帮助。 接下来就是用我训练完成的神经网络模型结合我所学专业(风景园林)研究领域问题完成论文撰写,希望能够投稿核心期刊成功。^ _^