【c++】类管理指针成员

c++编程提倡使用标准库,一个原因是标准库大胆减少对指针的使用。但是许多程序是离不开指针的。包含指针的类需要特别注意复制控制,原因是复制指针时只复制指针中的地址,而不复制指针所指向的对象。这样当把一个对象复制给另一个对象后,当改变一个对象后,另一个对象也会收到牵连。另外一个对象释放掉后,其指针已经被释放掉。而另一个对象还不知道,其实该对象中的指针已经成为悬垂指针。这样再操作就会出现错误。

1. 定义智能指针类

原理:定义一个计数的类,所有复制的都是指向这一个类,每复制一次,该类加1一次;每析构一次,该类减1一次。当次数为0时,释放掉动态申请的空间。

图例:

1)定义一个对象

【c++】类管理指针成员

 

2)复制一个对象

【c++】类管理指针成员

【c++】类管理指针成员
#include <iostream>
#include <string>
using namespace std;

class HasPtr;
//定义计数类
class U_Ptr { //没有访问标号,默认为private,保证类的隐私,但是友员类可以随意访问(包括private) friend class HasPtr; U_Ptr(int *p) : ip(p), use(1) {} ~U_Ptr() { cout << "hello" << use << endl; delete ip; } int *ip; size_t use; //次数 }; class HasPtr { public: HasPtr(int *p, int v) : ptr(new U_Ptr(p)), val(v) {} HasPtr(const HasPtr &orig) : ptr(orig.ptr), val(orig.val) { ++ptr->use; } HasPtr& operator=(const HasPtr &orig); ~HasPtr() { cout << "hahha::" << ptr->use << endl; if(--ptr->use == 0) delete ptr; } private: U_Ptr *ptr; int val; }; HasPtr& HasPtr::operator=(const HasPtr &orig) { ++orig.ptr->use; if(--ptr->use == 0) delete ptr; ptr = orig.ptr; val = orig.val; return *this; } int main() { int i = 56, j = 12; int *p = new int(56); HasPtr hasptr(p, j); HasPtr hasptr2(hasptr); }
【c++】类管理指针成员

2. 定义值型类

给指针成员提供语义值。具有值语义的类所定义的对象,其行为很像算术类型的对象:复制值型对象时,会得到一个不同的版本。对副本的改变不会反映在原有对象上。

【c++】类管理指针成员
#include <iostream>
#include <string>
using namespace std;

class HasPtr
{
    public:
        HasPtr(const int &p, int v) : ptr(new int(p)), val(v) {}
        HasPtr(const HasPtr &orig) : ptr(new int(*orig.ptr)), val(orig.val) {  } //复制值型对象时,会得到一个不同的版本
        HasPtr& operator=(const HasPtr &orig);
        ~HasPtr() { delete ptr; }
    private:
        int *ptr;
        int val;
};

HasPtr& HasPtr::operator=(const HasPtr &orig)
{
    *ptr = *orig.ptr;                                                        //赋值时,只改变指针指向的值,但是指针是不变的
    val = orig.val;
    return *this;
}

int main()
{
    int i = 56, j = 12;
    HasPtr hasptr(i, j);
    HasPtr hasptr2(hasptr);
    hasptr2 = hasptr;
}
【c++】类管理指针成员

 

 



本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/p/3503309.html

上一篇:c++ 静态类成员函数(static member function) vs 名字空间 (namespace)


下一篇:IOS推送功能的实现(javapns)