C++对象模型 第六章 执行期语意学

来源:互联网 发布:网络推广手段 编辑:程序博客网 时间:2024/05/18 11:27
第六章  执行期语意学
1)munch策略:一个可移植但成本颇高的静态初始化(以及内存释放)方法,称它为munch。一个munch策略包括①为每一个需要静态初始化的文件产生一个_sti()函数,内含必要的constructor函数。②在每一个需要静态的内存释放操作的文件中,产生一个std()函数③一个可以调用_sti()函数的_main()函数
int main()
{
_main();//Invoke _sti_XXX();
//....
exit();//_invoke _std_XXX();
}




2)对象数组
void *vec_new(void *array, size_t elem_size,int elem_count, void (*constructor)(void *),void (*destructor)(void*,char));
//将default constructor施行于class objects所组成数组的每一个元素上。
size_t elem_size:sizeof(point)


3)new运算符的两个分离步骤:int *pi =new int(5);
①int *pi;
②if(pi=_new(sizeof(int)))*pi=5;


new 运算符实际上总是以标准c malloc函数完成。


4)delete运算符
if(pi!=0)
_delete(pi);


5)针对数组的new语意
当我们写 int *p_array = new int[5];时,vec_new()不会真正被调用,因为它的主要功能是把default constructor施行于class objects所组成的数组的每一个元素上。调用的是new运算符:int *p_array=(int *)_new int(sizeof(int)*5);


如果:struct simple_aggr{float f1,f2;};
当我们写 simple_aggr *p_aggr=new simple_aggrs[5];是vec_new()也不会被调用。为什么?simple_aggr并没有定义一个constructor或destructor,所以配置数组以及清除数组的操作,只能单纯地获得内存和释放内存而已。




class point{
public:
point(){cout<<"point::point!"<<endl;}
virtual ~point(){ cout<<"point::~point~"<<endl; }
};
class point3d:public point{
public:
point3d(){ cout<<"point3d::point3d!"<<endl; }
virtual ~point3d() { cout<<"point3d::~point3d"<<endl; }
};


在我们执行:point *ptr= new point3d[10];交替出现
"point::point!“
"point3d::point3d!“
10次。


当我们执行delete []ptr时也会 执行10次析构


6)placement operator new语意
有一个预先定义好的重载new运算符,称为placement operator new。它需要第二个参数,类型为void*。调用方法如下:
point2w *ptw=new(area) point2w;其中area指向内存中的一块,用以放置新产生出来的point2w对象。
等价于
point2w *ptw=(point2w*) area;
if(ptw!=0)
ptw->point2w::point2w();




如果placement operator在原已经存在的一个object上构造新的object,而该既存的object有个destructor,这个destructor不会被调用。调用该destructor的方法之一是将那个指针delete掉。


注意:delete和析构的区别
delete ptr;会删除ptr指向的内存


至于area所表现的真正指针类型。C++ Standard 说它必须指向相同类型的class,要不就是一块fresh内存,足够容纳该类型的object。注意,derived class 很明显并不在被支持之列。一般而言,placement new operartor 并不支持多态性。
例如:
point2w *p2w=new (area)point3w;
point3w的构造函数会导致严重的破坏。
上述语句,等价于:
point2w *p2w=(point2w*)(area);
p2w->point3w::point3w();




7)Question:
struct Base{int j;virtual void f();};
struct Derived:public Base{void f();};
void forBar()
{
Base b;
b.f();
b.~Base();
new (&b)Derived;
b.f();//到底是哪一个f()呢
}
sizeof(Base)==sizeof(Derived)==8
vs2010下显示的是Base::f();


8)临时对象
Case 1: a+b 一定会产生一个临时对象
Case 2: c=a+b  c已经存在,用产生的临时对象赋值给c(拷贝构造函数) 然后再销毁临时对象
Case 3: T c=a+b 直接以拷贝构造的方式,将a+b的值放在c中,不会产生临时对象




9)
for(int i=0;i<N;i++)
a[i]=b[i]+c[i]-b[i]*c[i]
c++代码会产生五个临时变量
一个临时对象,用来放置b[i]*c[i]
一个临时对象,用来放置b[i]+c[i]
一个临时对象,用来放置两者的差

两个临时变量,分别用来放置第一个上述的第一个临时变量和第二个临时变量//   ?  ?


0 0
原创粉丝点击