1、哪些情况需要定制new和delete(effect c++ item50)
- 用来检测运用上的额错误
- 为了强化效能
- 为了收集使用上的统计数据
2、当自定义的operator new与operator delete是类的成员时,他们是隐式静态(static)的。这是因为,operator new总是在对象构造前调用,而operator delete是在对象析构后调用,即这两个函数在调用时并不存在对象,也就是说他们不属于对象,因此应该是static的。
3、显示调用析构函数
析构函数只是销毁对象,并不会释放对象本身所占内存,释放内存需要调用operator delete.
4、运行时类型识别(RTTI)
- typeid运算符,用于返回表达式的类型
- dynamic_cast运算符,用于将基类的指针或引用安全地转换为派生类的指针或引用
当我们想使用基类对象的指针或引用来执行某个派生类的操作时,若该操作是个虚函数则没啥问题,可以直接调用该对象的指针或引用所绑定的动态类型。若该操作是个非虚函数,则需要上面两个运算符将该基类对象的指针或引用转换成派生类的,即向下转换
5、dynamic_cast
dynamic_cast的使用形式如下:
- dynamic_cast<type*>(e)
- dynamic_cast<type&>(e)
- dynamic_cast<type&&>(e)
e的类型必须是type的公有派生类类型或公有基类类型或就是type类型,否则,转换失败。转换失败时若转换目标是指针类型则结果是0,如果是引用类型则抛出bad_cast异常。
class A
{
public:
virtual void test1(){ cout << "virtual test in A" << endl; }
};
class B :public A
{
public:
void test1(){ cout << "virtual test in B" << endl; }
void test2(){ cout << "normal test in B" << endl; }
};
void test()
{
A* pa = new B();
pa->test1();
pa->test2(); //错误 基类A中没有test2
B* pb = dynamic_cast<B*>(pa);
pb->test2();
}
6、typeid运算符
typeid运算符可以作用于任意类型的表达式。如果表达式是一个引用则返回该引用所引对象的类型,若是指针则返回则返回该指针所指对象类型的指针类型。不过,当typeid作用于数组或函数时,并不会执行向指针的标准类型转换,也就是说,如果我们对数组a执行typeid(a),所得结果是数组类型而非指针类型。
typeid是否需要运行时检查决定了表达式是否会被求值。只有当类型含有虚函数时,编译器才会对表达式求值,反之,如果类型不含有虚函数,则typeid返回表达式的静态类型。