C++细节

来源:互联网 发布:气象数据发布 编辑:程序博客网 时间:2024/06/05 11:13

1、尽量以const,enum,inline替换#define

const double testconstdefine=1.2;//外部常量class mainloop{private:    static const int numstatic;//类内部常量    enum {        numTurns=5    };    int scores[numTurns];};const int mainloop::numstatic=5;

2、const的使用

   const int* testa;//const在星号右边表示自身是常量,出现在星号左边表示所指物是常量 ,出现在星号两边,表示两者都是常量     const int* const testb;    std::vector<int> tesvec;    const std::vector<int>::iterator it=tesvec.begin();//it指针是常量,不可改 it++ 是错误 的    std::vector<int>::const_iterator itconst=tesvec.begin();//it指向 的东西是常量,不可以改,*itconst=10是错误 的

3、赋值与初始化的区别

mainloop::mainloop():stringa("tests"){    stringa="tests";}

初始化是默认会调用的,如果没有初始化,系统会调用stringa的默认构造函数进行初始化。而如果用赋值的话,系统默认做的事会白做,影响效率。

c++初始化类的顺序:先base class 后继承的class


4、编译器暗自为class创建default构造函数 ,copy构造函数 ,copy assignment构造函数 

如果要驳回编译器的自动行为,可将该函数声明为private并且不予实现是,或者通过基类来杜绝


5、base classes 应该声明一个virtual 析构函数,如果 class带有任何virtual函数,它就应该拥有一个virtual析构函数 

class的设计目的如果不是作为base class使用,或者不是为了具备多态性,就不应该声明为virtual 析构函数 



6、在构造函数和析构函数中不要调用virtual函数,因为有可能会调用 不到真正想要的函数

7、operator=返回一个引用


8、四种转型

const_cast<T>(expression)  去掉const

dynamic_cast<T>(expression)安全向下转型 ,用来决定某对象是否归属继承体系中的某个类型

reinterpret_cast  低级转型

static_cast   强迫隐式转型


尽量避免使用dynamic_cast,影响效率


9、继承类的名称会遮盖基类的名称,如果想让被遮盖的名称再见天日,可使用using声明式



10、newoperator newplacement new

class MyClass {…};

MyClass * p=new MyClass;

这里的new实际上是执行如下3个过程:

1调用operator new分配内存;

2调用构造函数生成类对象;

3返回相应指针。

operator new就像operator+一样,是可以重载的

placement newoperator new的一个重载版本,只是我们很少用到它。如果你想在已经分配的内存中创建一个对象,使用new是不行的。也就是说placement new允许你在一个已经分配好的内存中(栈或堆中)构造一个新的对象。原型中void*p实际上就是指向一个已经分配好的内存缓冲区的的首地址。我们知道使用new操作符分配内存需要在堆中查找足够大的剩余空间,这个操作速度是很慢的,而且有可能出现无法分配内存的异常(空间不够)。placement new就可以解决这个问题。我们构造对象都是在一个预先准备好了的内存缓冲区中进行,不需要查找内存,内存分配的时间是常数;而且不会出现在程序运行中途出现内存不足的异常。所以,placement new非常适合那些对时间要求比较高,长时间运行不希望被打断的应用程序。


使用方法如下:

1. 缓冲区提前分配

可以使用堆的空间,也可以使用栈的空间,所以分配方式有如下两种:

class MyClass {…}; 
char *buf=new char[N*sizeof(MyClass)+ sizeof(int) ] ; 或者char buf[N*sizeof(MyClass)+ sizeof(int) ];

2. 对象的构造

MyClass * pClass=new(buf) MyClass;

一旦这个对象使用完毕,你必须显式的调用类的析构函数进行销毁对象。但此时内存空间不会被释放,以便其他的对象的构造。

pClass->~MyClass();


0 0
原创粉丝点击