C++自学笔记_定义智能指针类_《C++ Primer》

包含指针的类要特别注意复制控制,原因是复制指针只复制指针中的地址,而不会复制指针所指向的对象。

C++类采用以下3种方法之一管理指针成员:

(1) 指针成员采取常规指针型行为。这样的类具有指针所有的缺陷但是无需特殊的复制控制。

(2) 类可以是实现“智能指针”行为。指针所指向的对象是共享的,但类能够防止悬垂指针。

(3) 类采取值型行为。指针所指向的对象是唯一的,由每个类对象单独管理。

这里总结第(2)种方法——采用定义智能指针类

智能指针类的思想在于:

第(1)种方法中,所有的对象中的指针都直接指向同一个基础对象(比如一个int型对象),这样导致的结果是其中任何一个对象进行析构都会把这个

基础对象给delete,此时别的对象中的指针成员已经成为了一个悬垂指针了。

而第(2)种方法,所有的对象中依旧有指针成员,但是此时新增一个计数类,每个计数类对象分别指向不同的基础对象,但这一切对使用者来说是

透明的。当我定义的类对象中的指针要指向一个基础对象时,我们不把类对象的指针直接指向这个基础对象,而是把这个对象的指针指向定义的

计数类对象,计数类对象指向我们原本要指向的基础类对象,计数类对象包含两个属性:一个指向基础对象的指针、一个计数器。

example:
#include <iostream>

using namespace std;

class HasPtr;    //HasPtr类的声明

/*U_ptr是一个计数类,用来统计指向某个int对象的HasPtr对象的个数*/
class U_ptr{
    friend class HasPtr;
    U_ptr(int *p):ip(p),use(1){ }   //构造函数
    ~U_ptr(){ delete ip; }
    int *ip;            //不直接通过HasPtr对象指向一个int对象,而是通过U_ptr对象来管理
    size_t use;         //记录有多少个HasPtr对象指向某个int对象
};

class HasPtr{
public:
    HasPtr(int *p,int i):             //构造函数,参数依旧是int*类型,通过调用U_ptr的构造函数来构造
        ptr(new U_ptr(p)),val(i){ }
    HasPtr(const HasPtr &orig):                      //复制构造函数,此时ptr和orig.ptr指向
        ptr(orig.ptr),val(orig.val){ ++ptr->use; }   //同一个U_ptr对象,并把这个U_ptr对象内的use加1
    HasPtr& operator=(const HasPtr&);
    ~HasPtr() { if(--ptr->use==0) delete ptr; }      //析构函数,只有当析构了以后会
                                                     //导致U_ptr对象内的use减小到0才delete
    int* get_Ptr()const { return ptr->ip; }
    int get_int()const { return val; }
    void set_ptr(int *p){ ptr->ip=p; }
    void set_int(int i){ val=i; }
    int get_ptr_val()const { return *ptr->ip; }
    void set_ptr_val(int i){ *ptr->ip=i; }
private:
    U_ptr *ptr;        //现在HasPtr对象不再直接指向int对象,而是指向计数类对象
    int val;
};

HasPtr& HasPtr::operator=(const HasPtr &obj){
    ++obj.ptr->use;
    cout<<"obj.ptr->use="<<obj.ptr->use<<endl;
    if(--ptr->use==0){
        cout<<"ptr->use="<<ptr->use<<endl;
        delete ptr;
    }
    ptr=obj.ptr;
    val=obj.val;
    return *this;
}

int main()
{
    int num1=10;
    int num2=11;
    HasPtr obj1(&num1,20);
    HasPtr obj2(&num2,22);
    cout<<"obj1:"<<endl;
    cout<<"obj1.get_int(): "<<obj1.get_int()<<endl;
    cout<<"obj1.get_ptr_val(): "<<obj1.get_ptr_val()<<endl<<endl;
    cout<<"obj2:"<<endl;
    cout<<"obj2.get_int(): "<<obj2.get_int()<<endl;
    cout<<"obj2.get_ptr_val(): "<<obj2.get_ptr_val()<<endl<<endl;
    obj1=obj2;
    cout<<endl<<"obj1:"<<endl;
    cout<<"obj1.get_int(): "<<obj1.get_int()<<endl;
    cout<<"obj1.get_ptr_val(): "<<obj1.get_ptr_val()<<endl<<endl;
    return 0;
}
编译运行后的结果:
obj1:
obj1.get_int(): 20
obj1.get_ptr_val(): 10

obj2:
obj2.get_int(): 22
obj2.get_ptr_val(): 11

obj.ptr->use=2
ptr->use=0

obj1:
obj1.get_int(): 22
obj1.get_ptr_val(): 11

Process returned 0 (0x0)   execution time : 2.007 s
Press any key to continue.
 
 
时间: 2024-10-18 13:54:08

C++自学笔记_定义智能指针类_《C++ Primer》的相关文章

13.5.1. 定义智能指针类

#include <iostream> #include<string> #include<set> using namespace std; //智能指针的使用 //智能指针类 class U_ptr { friend class hashptr; int *ip;//在hashptr中实际的需要定义的指针成员 size_t use;//使用次数的计数 U_ptr(int *p):ip(p),use(1){}//合成构造函数 ~U_ptr(){delete ip;}/

【C++】智能指针类和OpenCV的Ptr模板类

智能指针类 引用计数 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count).智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象.引用计数为0时,删除对象. 其基本使用规则是: 每次创建类的新对象时,初始化指针并将引用计数置为1.当对象作为另一对象的副本而创建时,复制构造函数复制指针并增加与之相应的引用计数的值.对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数的值(如果引用计数减至0,则删除对

智能指针类

//智能指针类 //---------------------------------------- //1.基数据放在使用计数类中 //实际类指向->使用计数类->基数据 //使用计数类 class U_ptr{ friend class Hasptr;//友元类 int *ip;//这个就是要保护的基数据 size_t use; U_ptr(int *p):ip(p),use(1){} ~U_ptr(){delete ip;} }; class Hasptr//实际类 { public:

智能指针类模板(五十)

我们之前在 C++ 的学习中学习了有关智能指针的知识.那么智能指针的意义是现代 C++ 开发库中最重要的类模板之一:是 C++ 中自动内存管理的主要手段,它能够在很大程度上避开内存相关的问题.在 STL 标准库中的智能指针为 auto_ptr,它的特点是:1.生命周期结束时,销毁指向的内存空间:2.不能指向堆数组,只能指向堆对象(变量):3.一片堆空间只属于一个智能指针对象:4.多个智能指针对象不能指向同一片堆空间. 下来我们就来使用下 auto_ptr 智能指针 #include <iostr

C++智能指针类模板

1.智能指针本质上是一个对象,这个对象可以像原生的一样来进行使用.原因是智能指针对象对应的类中,将指针相关的操作都进行了重载操作处理,所以才会达到这种像是原生的效果. 2.智能指针的意义: 现在C++开发库中最重要的类模板之一 C++中自动内存管理的主要手段 能够在很大程度上避开内存相关的问题 3.在QT中开发库中也提供了智能指针类模板,在STL标准库中也提供了,在c++的标准库忘了什么名了中也提供了智能指针类模板.所以智能指针类模板在C++中的地位很重要 4.STL中的智能指针类模板 auto

第61课 智能指针类模板

1. 智能指针的意义 (1)现代C++开发库中最重要的类模板之一 (2)C++中自动内存管理的主要手段 (3)能够在很大程度上避开内存相关的问题(如内存泄漏.内存的多次释放等) 2. STL中的智能指针 (1)auto_ptr智能指针 ①生命周期结束时,销毁指向的内存空间 ②只能用来管理单个动态创建的对象,而不能管理动态创建的数组.即不能指向堆数组,只能指针堆对象(变量) int* pn = new int[100]; auto_ptr<int> ap(pn); //auto_ptr指向堆数组

[C/C++]_[中级]_[使用智能指针的方式释放malloc出来的堆空间]

场景: 1. 使用auto_ptr 的方式可以wrap类对象,  之后在方法结束后可以自动释放对象, 参考:这样在有条件判断的语句时可以省掉free语句或CloseHandle. http://blog.csdn.net/infoworld/article/details/9008911 2.C++的特性之一就是类对象(非返回值的对象)在方法结束后会自动调用析构函数,这样在析构函数里可以放一些释放资源的操作. 3. 这里实现了一个类似auto_ptr的类的实用Wrap类,可以参考根据自己需要自定

Python2.7自学笔记4——定义函数

使用关键字def定义函数 In [19]: def fib(n):    ....:     a, b = 0, 1    ....:     while a < n:    ....:         print a,    ....:         a, b = b, a+b    ....:          In [20]: fib(2000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 函数可以直接传递给变量,相当于重新

C++学习笔记8-操作符&amp;指针

1.  重载操作符 赋值操作符的返回类型应该与内置类型赋值运算返回的类型相同.内置类型的赋值运算返回对右操作数的引用,因此,赋值操作符也返回对同一类类型的引用.例如,Sales_item的赋值操作符可以声明为: class Sales_item { public: // other members asbefore // equivalent to thesynthesized assignment operator Sales_item&operator=(const Sales_item &a