解析在main函数之前调用函数以及对设计的作用详解

   2015-09-08 0
核心提示:本篇文章是对在main函数之前调用函数以及对设计的作用进行了详细的分析介绍,需要的朋友参考下
前几天为新员工写一个简单的测试框架,可让他们方便的写测试用例并且执行。期间遇到一个问题就是如何让他们增加测试用例而用不影响测试框架的代码?c++的单件模式可以解决这个问题,但是其中一个难点是要在main之前注册单件。c++可以通过构造函数来实现注册,c如何注册?
最后查了下资料,原来可以定义在main之前调用的函数!有了这个特性可以改善c的模块化设计。
特性介绍:
如果想定义在main函数之前调用的函数,可以在函数的声明之后加上一句“__attribute__((constructor))”,如下:
int before()__attribute__((constructor));
如果想定义在main函数之后调用的函数,可以在函数的声明之后加上一句“__attribute__((destructor))”,如下:
int after()__attribute__((destructor));
可以看得出来,应该类似于c++中的构造和析构。

一些细节问题:
写测试代码测试了一下这个程序,发现几点:
1、before在main之前调用,调用之前,各个全局变量已经完成初始化。也就是说,这些函数是在全局变量初始化之后,main函数之前调用的。这一点是非常重要的,否则可能会引起很多的问题。
2、after在main之后调用,但是有一点比较特殊,必须是在main中return的话才执行,否则,需要通过atexit执行某函数。这个特性目前对我没有太大的用处。
3、在main函数之前调用的函数可以声明为static。
4、在main函数之前调用的函数可以调用多个。这里就有一个问题,就是这些函数的调用顺序的问题。这个问题首先是一个设计的问题,也就是,我们应该设计这些函数为顺序无关的函数。另外,调用顺序和编译的顺序相关,我在linux下使用make进行编译,发现最后编译的源文件中的函数会最先调用。
5、可以在库(动态库和静态库)中定义这样的函数。

用对设计的作用:
1、可以优化c++中的单件模式。参考《设计模式》
单件模式有一个最大的特点就是可以在运行过程中连接单件。如果使用条件语句来决定使用哪个单件硬性限定了可能的单件集合。所以,书中引入了一个单件注册表的概念,书中对单件注册表的初始化采用的是如下的做法:
首先定义一个单件类,在单件类的构造函数中调用单件的注册函数注册自身:
复制代码 代码如下:

MySingleton::MySingleton()
{
...
Singleton::Register("MySingleton", this);
}

这个函数是怎么被调用的那?可以定义一个静态实例:
static MySingleton theSingleton;
这样就会在main函数之前调用MySingleton的构造函数来构造这个静态实例,从而达到像注册表注册的目的。
这个方案有个缺点:它能够成功存在一个前提,就是在theSingleton实例化之前,单件注册表列表必须存在,否则会失败。则其实只是一个可能失败的点,如果MySingleton还应用其他的全局变量,则可能这个时候这些全局变量还没有初始化。
解决这个问题的一个方案就是将单件注册的时间由构造函数移到main函数之前调用的函数中来。
定义函数:
复制代码 代码如下:

static void before_main()
{
Singleton::Register("MySingleton", &theSingleton);
}
声明:
staitc void before_main()__attribute__((constructor));

before_main会在main函数之前调用,而调用时全局变量已经全部初始化,这样就可以避免上面的问题。
其实单件不单单可以在c++(面向对象)中使用,也可以在c中使用。而且有了c的这个特性后,单件更好用。
2、构造插件开发框架,而不用对框架进行更改。
构造插件开发框架的一个问题是:如何新增一个插件而不用修改主框架代码就可以调用插件代码。一般情况下都会使用插件注册机制。也就是框架对外提供注册接口,插件使用这些接口进行注册。c要实行此功能,一个可行的方案是在插件中定义main之前执行的函数,在此函数中调用插件注册接口完成注册。(注:这里讨论的是插件的静态加载)。
3、一个模块有一些初始化工作要做,使用这种机制可以不更改main或者函数。
抛开插件框架,使用这个特性也可以对c的模块化进行很多优化。比如,可以把各个模块的初始化工作放在main之前进行从而防止对main的频繁修改。
注:本文描述的环境为linux c,c++。
 
标签: matlab 函数调用
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 如何在Abaqus的python中调用Matlab程序
    目录1. 确定版本信息2. 备份python3. 设置环境变量4. 安装程序5. 调试运行参考资料Abaqus2018操作系统Win10 64位Python版本2.7(路径C:\SIMULIA\CAE\2018\win_b64\tools\SMApy\python2.7)2. 备份python将上述的“python2.7”文件夹复制出来,避免因操作错误
    03-16
  • 如何将极坐标数据转换为笛卡尔坐标系并绘制[MATLAB]
    如何将极坐标数据转换为笛卡尔坐标系并绘制[MAT
    你想做的事考虑根据与原点的距离 $r$ 和 $xy$ 平面上的角度 $heta$ 绘制数据 $P(r, heta)$。例如,雷达获取的信号包含有关目标范围 $r$ 和方位角 $heta$ 的信息。就是下图。在本文中,$heta$ 是从 $x$ 轴测量的角度。显示示例考虑创建依赖于 $r, heta$ 的虚拟
    03-16
  • 【MATLAB与机械设计】一维优化进退法确定初始区间
    【MATLAB与机械设计】一维优化进退法确定初始区
    在讨论一维搜索时,首先保证搜索区间函数具有单峰性,也就是在区间[a,b]中函数是凸函数,对于求极小值问题,函数值具有高—低—高的特性,在区间[a,b]上有唯一的最小值。1,方法的建立2.进退法确定搜索区间的程序框图3,根据上述的程序框图,编写的MATLAB程序
    03-08
  • 用于微型四轮驱动的 6T 小齿轮原型和使用 MATLAB 的 FEM 结构分析
    用于微型四轮驱动的 6T 小齿轮原型和使用 MATLA
    介绍我使用迷你 4WD 套件使用 Raspberry Pi 制作机器人汽车。定制零件丰富且方便,因为它们在附近的商店很容易买到。但是,由于Mini 4WD的速度非常快,因此在低速时很难控制速度。因此,我使用 3D 打印机制作了自己的 6T 小齿轮,并尝试改变齿轮比。 成型小齿
    03-08
  • ROS与Matlab系列:一个简单的运动控制 基于matl
    转自:http://blog.exbot.net/archives/2594Matlab拥有强大的数据处理、可视化绘图能力以及众多成熟的算法函数,非常适合算法开发;在控制系统设计中,Simulink也是普遍使用的设计和仿真工具。而ROS系统,则是一种新的标准化机器人系统软件框架。通过ROS,你
    02-10
  • matlab 遍历结构体struc的成员
    MATLAB中专门用于对结构数组的操作的函数并不多,通过 help datatypes获取数据类型列表,可以看到其中的结构数据类型的有关的函数,主要如表4.3.1所示。表4.3.1 结构数组的操作函数函数名             功能描述 deal                 把输入处
    02-09
  • 02-09
  • schroeder reverb matlab实现
    schroeder reverb matlab实现
    原理参考:Natural sounding artificial reverberation combFilter.m:function output = combFilter(delay, gain, input)fs = 48000;delaySample = int32(delayTime * fs / 1000);B = [1 zeros(1, delaySample - 1)];A=[1 zeros(1, delaySample - 2) -gain];
    02-09
  • C/C++中调用matlab引擎计算 matlab转c
    原帖地址:http://blog.sina.com.cn/s/blog_6adcb3530101cvot.html一,在linux环境使用matlab引擎必须先进行一些必要的配置1,matlab引擎依赖/bin/csh启动,所以不管你使用何种shell,都必须安装csh。**2,matlab引擎依赖的动态库文件目录必须在系统当前的
    02-09
  • MATLAB 图像放大/缩小,双线性插值
    MATLAB 图像放大/缩小,双线性插值
    半年前写过matlab最邻近插值的图像缩放,没怎么考虑边界问题。更早之前用Opencv写过双线性插值图像放大,不过写的比较混乱。所以这里用matlab重新再清楚的写一遍。 1 close all; 2 clear all; 3 clc; 45 m=1.8;%放大或缩小的高度 6 n=2.3;%放大或缩小的宽度 7
    02-09
点击排行