智能指针 (1)

目录

为什么要讲讲智能指针, 因为发现很多人根本说不出什么是智能指针, 一说到智能指针就会提引用计数。引用计数不是智能指针, 引用计数只是智能指针的一种实现方式。

(1) 何为智能指针?

        说到智能指针, 我们首先应该说一下普通指针的优缺点。

                优点: 灵活, 可以直接获取内存所指向数据。

                缺点: 必须手动管理所指向内存, 容易出bug, 维护困难。

        智能指针应该保持普通指针优点, 剔出其缺点。

        于是智能指针可以定义为: 具有指针性质, 但是能够自动释放内存(资源)的结构体(类)。

(2) 如何保持指针的性质?

        指针的两大操作是: 

            1) 取值:  *p。

            2) 指向成员: p->member。

      因此智能指针必须要重载operator* 和 operator->。

(3) 如何自动释放内存?

        自然是在析构函数中销毁。

有了以上的思路, 现在我们可以尝试着写代码了,我们以int型指针为例,最后我们可以用模板实现。

智能指针 (1)_第1张图片
(1)

这样就会出现两个问题,a)如何判断是否为空指针,b) copy构造函数和赋值运算符如何写?

我们可以增加一个get函数来获取裸指针,或者重载bool转换运算符。

智能指针 (1)_第2张图片
(2)

copy构造函数和赋值运算符一般有以下几种思路

1)让 拷贝构造函数和赋值运算符不可用。

2)深copy rawPtr_。

3)浅copy rawPtr_。

1) Disable copy构造和赋值运算符是有实用价值, 因为很多场景是拥有关系, 比如一个类A拥有一个指针p, 那我们可以修改为这个类A拥有一个p的智能指针,由于智能指针的自动析构,就免去了在类A的析构函数中显式删除p。

智能指针 (1)_第3张图片
(3)

2) 深copy指针和类的一般实现原则其实并无差异,这样就使新建了一个SmartIntPtr,那么可以用SmartIntPtr sp2(new int(*sp1))替换, 也可以新建了sp2后重新赋值即:*sp2 = *sp1。

智能指针 (1)_第4张图片
(4)

深copy必须要考虑被copy的指针是否为空。

3)浅copy指针,这个实现起来很方便。

智能指针 (1)_第5张图片

但是这里面有个问题, 内存怎么删除, 所有的copy都拥有这个指针,都会在析构函数中删除内存,势必产生问题。

我们在回到一个原始的问题? 一个指针怎么去使用,一般有两种方法:

1)指针指关联到一个对象, 并且指针在对象创建时被创建。

2)指针只在一个对象关联,对象负责删除,但是指针是从对象外界传递进对象的。

3)指针被很多对象关联, 但是只有一个地方删除它,关联它的地方都可以修改它的内容。

第1)与2)类型,我们在上面的SmartIntPtrDisableCopy和SmartIntPtrDeepCopy里面已经基本实现了。3)如何处理,SmartIntPtrShallowCopy的思想, 但是如何解决指针多重删除问题?还有问题是智能指针的传递,如果Disable copy, 那么就无法值传递, 如果是Deep copy那么每次都要重新建立申请一份内存,用完之后就自动delete,效率上不高。而且被传递的指针不是原来的指针了。

我们将在下面章节中,对以上两个问题(1)指针的传递和(2)共享指针的构析的解决方法。

下一章:智能指针(2)

目录

你可能感兴趣的:(智能指针 (1))