执行期语意学

对象的构造和析构
讲解在 以下几种情况下 编译器是如何安插构造和析构函数?
1.全局对象
2.局部静态对象
3.数组对象
1)全局对象
Matrix g_identity;
main() {
Matrix m =  g_identity ;
}
c++保证了在main函数中第一次用到g_str之前,将g_str构造出来,在main()函数结束之前将g_str毁掉。
一个global class只能够被一个常量表达式(编译期间求其值得那种)。非class全局变量在编译期间可以放置在data segment并且指定特定的值(如int g_tmp),但是如果是class全局变量,可以放置在data segment并且制定为0,但是构造函数一定要到程序运行时才会实施。
针对class全局变量采用munch策略:
1. 为每一个需要静态初始化的文件产生一个_sti函数。如之前的g_identity,会在matrix中产生_sti函数(static initialization)
_sti_matrix_c_identity() {
g_identity.Matrix::Matrix();
}
2.类似会产生一个_std函数,针对每个静态初始化对象条用destructor
3.提供一组runtime library“munch”函数:一个_main()函数(用以调用可执行文件中的所有_sti()函数),以及一个exit()函数(所有_std()函数)
int main() {
_main(); //调用所有的_sti_xxx
...
_exit(); //调用所有的_std_xxx
}
如何收集各个object file中的_sti()函数和std()函数呢?
nm命令( 列出一个目标文件中的各种符号),将符号表的信息导入到munch程序,然后通过munch根据符号表的名称,搜寻_sti和_std开头的名称,将这些函数名称加入到一个jump table中,接下来将这个表格写入到program text文件中,然后cc命令重新期货,将这个内含jump table的文件加以编译,整个可执行文件然后被重新链接。

2)局部静态对象
const Matrix& identity() {
static Matrix m;
...
}
局部静态对象必须只能够构造和析构一次,采用方法导入一个临时性对象用以保护m的初始化操作,第一处理identity函数,这个临时对象为false,调用过之后设置回true,destructor类似。

3)数组对象
Point knots[10];
需要配置内存来存10个连续的Poingt元素,同时调用default构造函数,轮流施于每个元素之上。
void* vec_new {
void* array,  // 数组起始地址
size_t elem_size,  //每个object的大小
int elem_count,  //元素个数
void (*constructor)(void*),
void (*destructor)(void*, char)
}
针对编译器很可能转换为
vec_new(&knots, sizeof(Point), 10, &Point::Point, 0);
释放的时候也会有类似的vec_delete.
void* vec_delete {
void* array,  // 数组起始地址
size_t elem_size,  //每个object的大小
int elem_count,  //元素个数
void (*destructor)(void*, char)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值