class Int{
public:
const Int operator++(int); //后置++
Int & operator++(); //前置++
Int & operator+=(int);
};
Int& Int::operator++(){
*this += 1; //使用operator+=
return *this;
}
const Int Int::operator++(int/*不添加形参防止编译器警告*/){
Int old_value = *this;
++(*this); //由本身前置实现
return old_value;
}
//重载&&,不能控制参数评估顺序
if (exp1 && exp2) ...
//可能是以下两种形式
if (exp1.operator&&(exp2)) ... //成员
if (operator&&(exp1, exp2)) ... //全局
当写出以下代码便是使用到了语言内建的new operator。
string *ps = new string("hello world");
new operator的行为是固定的,不可改变的,它的动作分为两方面
1. 为了放置某个对象分配足够的内存空间。
2. 在该内存空间上调用对象的构造函数,设定初始值。
其中针对1条款,我们是可以定制的,也就是更改原始内存分配的行为,即重载operaotor new,通常声明如下,返回值为原始未初始化的内存。
void* operator new(size_t size);
类似于于malloc,operator new的唯一任务就是分配内存。它并不知道什么是构造函数以及如何将内存转换为对象。可直接调用它分配内存如下。
void *raw_memory = operator new (sizeof(string));
对于代码
string *ps = new string("hello world");
或多或少反应如下行为
void *memory = operator new(sizeof(string)); //取得原始内存
call string::string("hello world") on memory; //内存对象初始化
string *ps = static_cast<string*>(memory); //ps指向对象
以上说明的new operator将内存分配、对象构建一气呵成。但有时候我们希望在自己已有内存空间上来构建对象。此时有一个特殊版本的operator new称为placement new允许那样做。
class C{
public:
C();
...
};
C* ConstructCInBuffer(void* buf, int size){
return new(buf) C(size);
}
其中 new(buf) C(size)
正是placement new的用法。buf为用户提供的用来接受构造好的对象的空间。Placement new的实现看起来如下:
void *operator new(size_t, void *location){
return location;
}
由于operator new的作用是分配原始内存,既然用户已经提供了内存空间,所以只是简单的返回该空间。
针对资源分配必须有匹配的资源释放。
当写出以下代码
std::string *str;
...
delete str;
代码必须做两件事:1. 析构str所指对象 2.释放该对象占用的内存。delete str
会导致编译器产生如下代码:
str->~string();
operator delete(str);
operator delete对于delete operator来说就如operator new对new operator。这里一个暗示是如果只是涉及原始的、未初始化的内存那么用operator new来分配、用operator delete来销毁。类似c语言中的malloc和free。
void *buffer = operator new (50*sizeof(char));
...
operator delete(buffer);