Stack Vs Heap

为什么要使用指针?

指针可以避免资源被重复创建,提高效率并且节约内存。有些类实例在逻辑上只需要存在一份即可,这种时候就可以只创建一次,然后别的对象通过指针来引用这个实例。

指针可以解耦两个物体的关系。如果类A是类B的成员变量,这往往在逻辑上等价于类B拥有类A(符合人类直觉)。如果类B在逻辑上并不拥有类A,但是确实需要知道一个类A来达成某种逻辑,这种时候就可以使用指针来解耦两者的关系。指针在逻辑上更像是一个连接两个物体的桥梁。比如:

struct Edge{
  node* desNode;
  node* SrcNode;
};

Edge是一条有向边,从srcNode指向desNode,但是逻辑上Edge并不拥有这两个节点。

指向栈资源的指针 Vs 指向堆资源的指针

指针不管是指向栈中的资源还是指向堆中的资源,都可以起到上述提到的作用,但是有一个很大的区别是指向栈中的资源必须被hard coded。因为栈的工作原理是不停地压栈和出栈,先进后出,栈中的资源如果不被hard coded到某个类成员将很快被释放掉,所以指向栈资源的指针作用很受限,无法实现运行时动态创建。

注意,如果通过把运行时动态创建的资源放到std::vector里,std::vector每次扩容都会重新分配内存并进行拷贝,因此资源还是会被反复创建,并且扩容前指向其中资源的指针也全部失效了,容易造成Bug。

Tips

是否需要使用指针以及该设计其指向栈还是堆可以通过一下两个逻辑判断