`
表情商店
  • 浏览: 2203 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

《深度探索C++对象模型》之执行期语义学

c++ 
阅读更多

全局对象:

C++程序中所有的global objects都被放置在程序的data segment中,如果显式指定给它一个值,此obejct将以该值为初值。否则object所配置到的内存内容为0。

int v1 = 1024;
int v2;

 其中v1和v2都被配置于data segment中,v1的初值为1024,v2的初值为0。

 

C语言略有不同,它并不自动给设定初值。在C语言中,一个全局对象只能够被一个常量表达式(可在编译时起求值得那种)设定初值。

 

局部静态对象:

假设有如下程序:

const Matrix& //Matrix为一个类
identity()
{
    static  Matrix mat_identity;
    //...
    return mat_identity;
}

 则局部静态对象保证了以下语义:

1,mat_identity的构造函数必须只能执行一次,虽然上述函数可能会被调用多次。

2,mat_indentity的西沟函数也必须只能执行一次。

老式的编译器会无条件的在程序起始时就构造对象,然而那会导致所有的局部静态对象都在程序起始时被初始化,即使它们所在的那个函数从不曾被调用过,新的编译器要求,只有在包含局部静态对象的函数被调用时才初始化相应的局部静态对象。

 

对象数组:

默认构造函数和数组:

 

new 和 delete 运算符:

运算符new的使用看起来似乎是个单一运算,比如:

int *pi = new int(5);

 实际上它是由两个步骤完成的:

1,通过适当的new运算符函数实例,配置所需的内存:

//调用函数库中的new运算符
int *pi = __new(sizeof(int));

 2,将配置得来的对象设立初值:

*pi = 5;

更准确的说,初始化操作只有在内存配置成功的情况下才会执行。

 

delete运算符的情况类似。

当程序员写下:

delete pi;

 如果pi的值是0,C++语言会要求delete运算符不要有操作,因此编译器必须为此调用构造一层保护膜:

if( pi != 0)
   __delete(pi);//注意:此操作并不会把pi自动清除为0。

 注意:上述new是针对内置类型int,因此不涉及构造函数和析构函数,如果是new一个类对象,则还要考虑相应的构造和析构函数。

比如有如下语句:

Point3d *origin = new Point3d;

 则它被转换为:

Point3d *origin;
//C++伪码
if( origin = __new( sizeof( Point3d ) ) )
    origin = Point3d::Point3d( origin );

 如果实现了异常处理,那么转换结果将更复杂:

//C++伪码
if( origin = __new( sizeof( Point3d ) ) )
{
    try{
        origin = Point3d::Point3d( origin );
    }
    catch(...){
        //调用delete函数以释放因new而配置的内存
        __delete( origin );
        //将原来的异常上传
        throw;
    }
}

 析构函数的操作极其类似

delete origin;

 会变成:

if( origin != 0 )
{
//C++伪码
Point3d::~Point3d( origin );
__delete( origin );
}

 new 运算符实际上总是以标准的C malloc()完成,相同情况,delete运算符也总是以标准的C free()完成。

extern void
operator delete( void *ptr )
{
   if( ptr )
      free( (char*)ptr );
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics