item 1:pointers 和references的区别:
1.pointers 不必赋初值,可以指向NULL。references必须赋初值,因为引用是匿名,在初始化的时候必须指名是引用的对象。
因此,如何指向(代表)的对象可以为空,选指针;不为空,选引用。
2.pointers可以被重新赋值,references不可以被重新赋值。
3.重载操作符时,必须返回对象时,用references。例如:<<,[]等
结论:当知道需要指向某个东西,而且绝不会改变其他东西,或是实现一个操作符而其语法需要无法由pointers达成,就该选择references。任何其他时候,请采用pointers。
item 2:最好使用C++的转型操作符
4个新的转型操作符(cast operations):static_cast, const_cast, dynamic_cast, reinterpret_cast
static_cast:用于基本类型的转型
c:(double)int , (int)char
c++:static_cast<double>int, static_cast<int>char
const_cast:用于改变常量性(const)
class Widget {...};
class SpecialWidge: public Widget {...};
void updata(SpecialWidget *psw);
SpecialWidget sw; // sw 是个 non-const 对象
const SpecialWidget& csw = sw; // csw是个const—reference,引用sw
update(&csw); //错误!const 类型不能传给 非const类型
c++:update(const_cast<SpecialWidget*>(&csw));//&csw的常量性被去除,csw引用的对象可以被更改
c:update((SpecialWidget*)&csw);//效果相同,c旧式转型
dynamic_cast:安全的向下转型(缺乏虚函数时或其他转型失败时,抛出异常
//接上例
Widget *pw = new SpecialWidget;
update(pw); // 错误!pw的类型是Widget*,但update()需要SpeialWidget*,需要向下转型
c:update((SpecialWidget*)pw)
c++:updata(dynamic_cast<SpecialWidget*>(pw));
reinterpret_cast:转换“函数指针”类型,不具有移植性
(“某些情况下这样的转型可能会导致不正确的结果,所以应该尽量避免将函数指针转型,除非已经走投无路,像是被逼到墙角,而且有一把刀子抵住你的喉咙。一把锐利的刀子,非常锐利的刀子。”)
略(希望我没有这一天)
item 3:绝对不要以多态(polymorphically)方式处理数组
item 8:了解各种不同意义的new和delete
一.new operator:即常用的new
例如:string *ps = new string(“Memory Management”);
new operator是不能被重载的。
这个new operator分为两个动作:
第一,在内存中开出你需要的一片存储空间。
第二,在这片存储空间中,调用构造函数,设定这片空间的初值。
对于第一个动作,可以利用operator new函数来分配一片原生内存空间。
对于第二个动作,我们无法调用一个构造函数。如果就是想要调用某个构造函数,可以稍加修改operator new在一片已经存在的内存中调用一个构造函数,这就是placement new函数。
1.operator new
声明如下:
void * operator new(size_t size);
这个函数返回一个void类型的指针,参数类型为size_t,(sizeof()操作符的返回类型就是size_t),size表示要开的空间大小。
operator new函数可以直接调用也可以用 new operator隐式调用(new operator 调用),直接方式如下:
// 直接调用
void *rawMemory = operator new(sizeof(string));
// 返回一个指针,指向可以一片容纳一个string大小的空间
和c中的molloc一样, operator new只负责分配空间,不调用构造函数。
隐式调用:直接使用new(常用的new),就会调用重载后的operator new函数替换默认的函数。
operator new算符可以重载(这就意味着你可以在分配内存空间的时候就设定初值。)
new的调用动作:
//当编译器看到如下句子
string *ps = new string("Memory Management");
//会产生一下代码,反映一下行为
void *memory = operator new(sizeof(string));
// 利用operator new分配内存空间
call string::string("Memory Management") on *memory;
//将内存中对象初始化
string *ps = static_cast<string*>(memory);
// 让ps指向新完成的对象
2.placement new
作用:在已经分配的空间中,调用构造函数,来构造一个对象。
placement new是特殊版本的operator new。其声明看起来如下:
void* operator new(size_t, void *location) {
return location;
}
具体用法如下:
#include <iostream>
using namespace std;
class A {
int a;
public:
A() {
cout << "A's constructor has been called!" << endl;
}
~A() {
cout << "A's destructor has been called!" << endl;
}
};
A* constructA(void* buffer) { // placement new
return new (buffer) A; // 调用placement new
}
int main() {
void* rawMemory = operator new(sizeof(A));// 利用operator new 分配一片原始空间
A* a = constructA(rawMemory);//利用placement new构造一个对象
a->~A(); // 调用析构函数
operator delete(rawMemory); //利用operator delete 回收内存空间
return 0;
}
二.delete operator
同样,我们常用的delete包括两步。1.调用析构函数。2.回收空间
相对应。可以把delete显式的拆成两个语句。如上面例子。先调用析构函数。再利用operator delete (void*)回收一片内存空间。