// Pseudo C++ Code
{
Point point;
// point.Point::Point() 一般被安插在这儿
...
// point.Point::~Point() 一般被安插在这儿
}
如果一个区段(译注:以 { } 括起来的区域)或函数中有一个以上的离开点,情况会稍微混乱一些。Destructor必须被放在每一个离开点(当时object还存活)
一般而言我们会把object尽可能放置在使用它的那个程序区段附近,这样做可以节省不必要的对象产生操作和摧毁操作,
由于这样的限制,下面这些munch策略就浮现出来了:

const Matrix& identity()
{
static Matrix mat_identity;
// ...
return mat_identity;
}
因为静态语意保证了 mat_identity 在整个程序周期都存在,而不会在函数 identity()退出时被析构,所以:
以下就是书中作者在cfront之中的做法。首先,我导人一个临时性对象以保护mat_identity 的初始化操作。第一次处理identity()时,这个临时对象被评估为false,于是constructor 会被调用,然后临时对象被改为true.这样就解决了构造的问题。而在相反的那一端,destructor也需要有条件地施行mat_identity身上,但只有在mat_identity已经被构造起来时才算数。要判断mat_identity是否被构造起来,很简单。如果那个临时对象为true,就表示构造好了。最后,destructor必须在“与text program file(也就是本例中的stat_0.c)有关联的静态内存释放函数(static deallocation function)”中被有条件地调用,可以理解为在整个程序退出之时按构造相反的顺序析构局部静态对象。
Point knots[ 10 ];
在cfront中,我们使用一个被命名为vec_new()的函数,产生出以class objects构造而成的数组。比较晚近的编译器,包括Borland、Microsoft和Sun,则是提供两个函数,一个用来处理“没有virtual base class”的class,另一个用来处理“内带 virtual base class”的class.后一个函数通常被称为vec_vnew().函数类型通常如下:


实际上背后做的工作则是:

如果你想要在程序中取出一个constructor的地址,这是不可以的。
运算符new的使用,看起来似乎是个单一运算。但事实上它是由两个步骤完成的:
寻找数组维度,对于delete运算符的效率带来极大的冲击,所以才导致这样的妥协:只有在中括号出现时,编译器才寻找数组的维度,否则它便假设只有单独一个objects要被删除。如果程序员没有提供必须的中括号,那么就只有第一个元素会被析构。其他的元素仍然存在——虽然其相关的内存已经被要求归还了。

将基类指针指向派生类数组,很容易出问题。
因为派生类和基类对象的大小是通常不一样的,对基类指针使用下标操作符时,编译器按基类对象大小寻址,而不是我们需要的派生类。
placement operator new 是重载 operator new 的一个标准、全局的版本,它不能够被自定义的版本代替。
用来在指定地址上构造对象,要注意的是,它并不分配内存,仅仅是 对指定地址调用构造函数。其调用方式如下:
Point *pt=new(p) Point;
它的实现方式异常简单,传回一个指针即 可:
void*
operator new(size_t,void *p ){//size_t被忽略
return p;
}
大多取决于编译器
对于一个下面这样的程序片段:
T a, b;
T c=a+b;
死板一点来讲,它应当产生一个临时对象用来存储a+b的结果,然后以临时对象作为初值调用拷贝构造函数初始化对象c。而实际上编译器更愿意直接调用拷贝构造函数的方式将a+b的值放到c中,这样就不需要临时对象,和它的构造函数和拷贝构造函数的调用了。
但是对于一个没有出现目标对象的表达式 a + b,那么产生一个临时对象来存储运算结果,则是非常必要的。
**很多时候,产生临时对象是必不可少的,但是何时摧毁一个临时对象才是最佳行为呢?过早或过晚都不太适合,过早有可能使得程序错误,过晚的话又使得资源没有得到及时回收。**对于下面的程序:
string s1("hello "), s2("world "),s3("by Adoo");
std::cout<<s1+s2+s3<<std::endl;
显然保存s1+s2结果的临时对象,如果在与s3进行加法之前析构,将会带来大麻烦。于是C++标准中有一条:
完整的表达式,是指涵盖的表达式中最外围的那个。我们再看上面那个字符串相加的表达式,当计算完成,而cout还未调用,此时我们析构掉存储最终结果的临时对象,岂不悲剧。其实上面的规定还有两个例外:
::string s1("hello ");
::string &s=s1+"world";