1) placement new
在c++中,我们常用new创建对象,然后用delete来释放对象,如果在new完对象后忘记释放对象,就会导致程序崩溃,内存泄露。placementnew为我们提供了一种机制可以实现自动释放对象,当然这只是其中的效果之一,更重要的是它可以在已有对象上创建对象,我们先来看一下它的声明:
void *operator new( size_t, void *p ) throw() { return p;}
从上可以看出,它只是返回了内存的地址,什么也没做, 我们再来看一下它的应用:
#include <new>
using namespacestd;
class A
{
public:
A() {}
};
class B
{
private:
char buffer[100];
private:
void test()
{
A* a = new (buffer) A();
}
};
int main(int argc, char* argv[])
{
B b;
b.test();
}
运行上面的程序你会发现,不需要释放new出来的A, 实现上,它是在buffer所指向的地址上创建了对象地址,这样当buffer自动释放时,它也就自动释放了。
注意:你可能已经发现了buffer创建在栈上,所以对应的new出来的A也是在栈上的,如果你想创建到堆上,buffer就需要用new了: char*buffer, 在B的构造函数中buffer= new char[100];, 然后在析构函数中delete[]buffer;
另外,如果你创建 的对象A需要析构的话, 只能手工析构,a->~A();
2) malloc, calloc, realloc
malloc:申请指定长度的内存空间, 未初始化,可以通过memset进行初始化。
calloc: 申请指定长度的空间并初始化为0.
realloc: 重新申请更多的空间,主要应用在动态数组上,如前面的例子,buffer= new char[100]; 当你觉得空间不够用了,需要更多的空间,可以通过realloc申请更多的空间。
3) struct, union
struct : 结构,在c中作为定义复杂数据类型, 在c++中,与class基本相同,struct在继承和缺省成员缺省情况下是public的,而c++的class是private的.
union: 联合, 它的长度取决于它的成员变量长度最大的那一个,在同一时间只有一个成员变量有效。一但给其中某一个成员赋值,其它成员变量就无效了。
4) const
我们先来看const的所有写法:
I) 定义变量
a. const int a = 10; // 变量a 为只读变量,其值不可改变 (事实是不一定)
int* pa = &a;
*pa = 20;
在c++中,这个定义将初视为常量,如int b[a];是正确的,但在c中推荐于宏。在c++中,还可以用const_cast将const去掉。
b. const int* a; (*a)不可变,a是指针,指向常量的指针,是可变的.
c. const (int*) a; a不可变,(*a)可变。即常量指针,指针不可变。
d. int* const a; a不可变,(*a) 可变。同上
e. const int * const a; a和(*a)都不可变,无意义。
f. int const a = 10; a为只读常量。
g. int const *a; (*a)不可变,a 可变。
h. (int*) const a; (*a) 可变,a 不可变。
i. int * const a; (*a) 可变,a不可变。
j. int const * const a; (*a)和a都不可变, 无意义。
规则:延着*号的左侧画一竖线, 右侧即为const,不可变(如果const在*的右边,则去掉*号), 用()括起来的作为一个整体,不参与规则(即竖线画在括号的右侧)。
II) 定义函数
a. 作为参数,在函数体的作用与I)相同。
b. 作为返回值1: const int Func(); 返回值不可变,此处无意义。
c. 作为返回值2: const Obj Func(); 返回对象的成员变量不可修改。
d. 作为返回值 3: int Func() const; 函数体内不可修改本类的成员变量。
e. 作为返回值4: const int* Func(); 返回常量指针, 调用该函数的方式:constint * a = Func();