zoukankan      html  css  js  c++  java
  • 【c++】类管理指针成员

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

    1. 定义智能指针类

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

    图例:

    1)定义一个对象

    2)复制一个对象

    #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); }

    2. 定义值型类

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

    #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;
    }
  • 相关阅读:
    Go 模板
    使用Go开发web服务器
    CLI:使用Go开发命令行应用
    MyBatis 注解使用动态SQL
    Tomcat 使用Redis存储Session
    [翻译] java NIO Buffer
    [翻译] java NIO Channel
    [翻译]java nio 概述
    [翻译] java NIO 教程---介绍
    接口的定义常量与使用
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3503309.html
Copyright © 2011-2022 走看看