首页 > 其他分享 >day08

day08

时间:2023-09-04 22:24:32浏览次数:38  
标签:day08 指向 内存 shared 异常 ptr 指针

一、智能指针     常规指针的缺点:         当一个常规指针离开了作用域时,只有该指针变量本身占用的内存空间(4或8字节)会被释放,而它指向的内存空间不会自动释放,当free、delete、delete[]语句忘记执行或者无法执行,形参内存泄漏         (如何定位内存泄漏、如何预防内存泄漏问题)
    智能指针的优点:         智能指针是一个封装了常规指针的类类型对象,并且重载了 * 和 ->运算符,使用起来与常规指针相似         当智能指针离开作用域时,它的析构函数一定执行,从而在析构函数中执行释放常规指针的操作,这样就做到了自动释放的效果,从而避免内存泄漏         智能指针是一个类模板             C++STL中提供了四种智能指针:auto_ptr、shared_ptr、unique_ptr、weak_ptr,在C++98标准中只有第一个智能指针auto_ptr,C++11只支持后三个,第一个被弃用,使用会产生警告     需要提供头文件 <memory>
    1、auto_ptr         采用独占拥有模式,不能同时有多个auto_ptr指向同一个内存,但是不能完全实现,有时候会指向同一个内存,有隐患         auto_ptr<int> p1(new int(123));         auto_ptr<int> p2; //可以悬空         p2=p1;  //允许,但p1转移了所有权给p2,p1可能变成空指针         *p1;    //可能段错误         注意:这种独占式不一定成立,p1是否转移给p2不确定
        使用格式:             1、auto_ptr<类型> 对象名(new 类型名);             2、类型* p = new 类型;                auto_ptr<类型> 对象名(p);     2、unique_ptr   独享指针         是auto_ptr的升级版,完全实现独占式拥有模式,保证同一时间中只有一个unique_pre指向某个内存         通过把拷贝构造、赋值操作声明为delete来实现不能给另一个unique_ptr对象赋值的效果         unique_ptr<int> p1(new int);         unique_ptr<int> p2;         p2 = p1;        //报错         p2 = unique_ptr<int>(new int);  //允许指向匿名unique_ptr对象的内存         p2 = unique_ptr<string>(new string("hehe"));
        可以通过C++的全局函数 move() 转移内存的指向给另一个unique_ptr         p2 = move(p1);  //让p2指向p1原来的内存,p1一定会变成空指针,p2在改变指向之前,会先释放自己原来的内存     3、shared_ptr    共享指针(强引用)         采用共享的拥有模式,可以允许拥有多个shared_ptr指向相同内存         当一个内存被shared_ptr指向时,内部有一个引用计数器+1         当指向该内存的某个shared_ptr离开作用域或者改变指向或者通过reset()时,引用计数器会-1         当该内存的引用计数器被减为0时,由最后一个离开的shared_ptr在结束前释放该内存         相关的成员函数:             get()         获取指向内存的地址编号             use_count()   获取引用计数器的值             unique()      判断指向的内存是否只有一个shared_ptr指向                 0不独占  1独占             reset()       放弃对内存的指向 计数-1           全局函数:             val2 = move(val1)   移动val1的值和使用权给val2             swap()              交换两个对象                 shared_ptr的循环引用问题:             当两个类(A B)中都有可以指向对方类型的shared_ptr智能指针成员变量(pB pA),并且在类外通过shared_ptr指向new出来的两个类对象(pa指向类A pb指向类B),并且让它们的成员变量pB pA 指向对方,此时构成循环引用,导致就算类对象pa pb销毁,但它们指向的对象的引用计数无法减为0(pA pB还在指向),导致无法释放对象内存,内存泄漏     4、weak_ptr 弱引用指针         weak_ptr是为了配合shared_ptr而引入的一种智能指针,它指向一个由shared_ptr管理的对象而不影响该对象的生命周期,也就是说将一个weak_ptr指向一个shared_ptr对象或者离开时都不会改变该对象的引用计数,只有当最后一个shared_ptr离开该对象才会销毁         weak_ptr更像是shared_ptr的一个助手,而不是独立的智能指针         因此当发生shared_ptr的循环引用产生死锁时,可以把其中一个类的shared_ptr成员变量改为weak_ptr,即可避免产生死锁
二、异常处理     程序的错误大致分三种:         语法错误、逻辑错误、运行时错误     运行时错误发生在程序运行期间发生的问题:除零、内存分配失败、非法访问内存、文件不存在、数组越界     C++的异常处理机制就是为了解决运行时错误而引入的     C语言中运行时错误如果不管,系统会执行默认操作,可能会让程序终止,也就是程序终止产生程序崩溃,也可能不终止,但是运行结果不正确     C++提供的异常处理机制,能够捕捉到运行时错误,至少提供了告诉调用者发生了什么事情导致终止的方式,然后再终止
三、如何抛出异常     throw 数据;     //  数据可以是任意类型     //  不要抛出局部变量的地址,因为该地址有可能被释放     //  抛出的数据不是直接传递给捕获的变量,而是先创建一个匿名对象存储该数据,然后传递该匿名对象
四、如何捕获异常     try{         // 可能会产生异常的代码或函数调用     }catch(类型名1& 变量名){         // 如果使用 类型 变量名 方式捕获异常,会对匿名对象再拷贝一次,浪费资源和时间,所以一般使用引用来获取该匿名对象,可以减少一次拷贝           // 进行异常处理     }catch(类型名2& 变量名){         //     }···
五、异常说明(异常规范)     返回值 函数名(形参列表)[异常说明throw(类型名1,类型名2)]     {
    }     例如:         void func(void)throw(类型1,类型2)         void func(void)throw()  //表示不抛异常     异常说明:相当于该函数的限制或承诺,只抛出说明过的异常类型,如果抛出说明外的类型,可以抛出,但是不能接住     但是不同编译器对异常说明的实现不同,有的听从,有的不听从     异常说明是C++98一项功能,C++11后就抛弃了,不建议使用     C++11中使用         void func(void) noexcept 替代     六、标准异常:     C++已经定义好的异常类,当对应的异常发生时,会自动地抛出定义好的对应的异常类对象     std::exception  所有标准异常类的父类,能够捕获所有的标准异常     std::bad_alloc  new分配内存失败时抛出的异常         std::bad_array_new_length 是它的子类 new分配内存的数量有误时会抛出     std::bad_cast   该异常可以通过 dynamic_cast 抛出             需要typeinfo头文件     std::bad_typeid 该异常可以通过 typeid 抛出         当获取具有多态属性的类型指针解引用的类型时,如果不能确定解引用后是哪个类型时,会抛出该异常             Base* b = new Base;             Base* b1 = new Son;             Base* b2 = NULL;             typeid(*b);      //类型Base             typeid(*b1);     //类型Son             typeid(*b2);     //抛异常
七、自定义异常类     通过设计一个继承了exception的异常类,可以个性化地抛出想要的异常     #include <iostream>     using namespace std;
    #define ZZERROR(...) ZZerror(__TIME__,__FILE__,__func__,__LINE__,__VA_ARGS__)
    class ZZerror : public exception     {         string time;         string file;         string func;         size_t line;         string error;     public:         ZZerror(const string& time,const string& file,const string& func,size_t line,const string& error):time(time),file(file),func(func),line(line),error(error){}         ~ZZerror(void){}
        const string& what(void)         {             return error;         }
        friend ostream& operator<<(ostream& os,const ZZerror& err)         {             return os << "time:" <<err.time << " file:" << err.file << " func:" << err.func << " line:" << err.line << " error" << err.error;         }     };
    void func(int num)     {         if(num < 100)             throw ZZERROR("num less 100");         else             cout << "good" << endl;     }
    int main(int argc,const char* argv[])     {         try{             func(10);         }catch(ZZerror& err){             cout << err << endl;             cout << err.what() << endl;         }     }
八、使用异常需要注意的问题:     1、不要抛出局部变量、对象的地址,而是抛出变量、对象本身     2、建议使用引用的方式来捕获异常,减少一次拷贝     3、不要再构造、析构函数中抛异常     4、在捕获异常时,先捕获子类类型,再捕获父类类型    

标签:day08,指向,内存,shared,异常,ptr,指针
From: https://www.cnblogs.com/ymy1/p/17678243.html

相关文章

  • 标准C++ -- day08
    一、类型信息运算符typeid在C++中typeid可以获取数据的类型,需要加头文件typeinfo通过find/usr/include-nametypeinfotypeid是运算符,执行运算符函数,执行的返回值类型是type_info类类对象type_info中有个name的成员函数type_info中还重载了==运算符,可以......
  • day08-字符串part01
    344. 反转字符串详解classSolution{public:voidreverseString(vector<char>&s){intleft=0;intright=s.size()-1;while(left<=right){//chartmp=s[left];//s[left]=s[right];......
  • 20天 hot 100 速通计划-day08
    二叉树94.二叉树的中序遍历给定一个二叉树的根节点root,返回它的中序遍历。示例1:输入:root=[1,null,2,3]输出:[1,3,2]示例2:输入:root=[]输出:[]示例3:输入:root=[1]输出:[1]提示:树中节点数目在范围[0,100]内-100<=Node.val<=100递归三部曲......
  • 初学C语言day08--字符串
    字符串字符:字符是在计算机中以整数形式存储的,在需要显示成字符时会根据ASCII表中对应的关系,来显示对应的符号或图案'\0'0空字符'0'48'A'65'a'97串:是一种数据结构,是由一组连续的若干个类型相同的数据组成,末尾有一个结束标志对于这种数据结构的处理......
  • day08
    模块的四种模式什么是模块?模块是一系列功能的集合体,而函数是某一个功能的集合体,因此模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成一个模块。如果这个py文件的文件名为module.py,模块名则是module模块的四种形式在Python中,总共有以......
  • Day08_字符串类型
    1.字符串优先掌握: 2.字符串_切片顾头不顾尾+步长: 3.反向切片: 4.长度、成员运算符、strip用法: 5.切分、循环: 6.strip、lstrip、rstrip用法: 7.lower、upper用法: 8.startswith、endswith: 9.split、rsplit用法: 10.join用法: 11.replace替换字......
  • Day08_for循环+print补充用法
    1.for循环和while循环取值: 2.for循环字典: 3.for循环字符串: 4.总结for循环和while循环的异同: 5.for循环控制循环次数:range() 6.for+break和for+else: 7.range(): 8.for+continue: 9.for循环嵌套: 10.print补充用法: ......
  • day08 8.1 安卓开发环境搭建
    【一】安卓开发环境介绍做安卓开发需要会Java开发需要安卓SDK需要一款编辑器需要软件测试环境(真机,虚拟机)早期开发安卓app需要使用eclipse+安卓SDK,自己搭建目前开发安卓app只需安装AndroidStudio可以直接通过AndroidStudio下载SDK编写完的代码要运行使用A......
  • day08 8.2 安卓开发项目简介
    【一】安卓项目目录结构(开发流程)【二】安卓项目目录结构├──.gradle#AndroidStudio自动生成的文件,会自动修改它的,项目打包时也会删除;├──.idea#AndroidStudio自动生成的文件,会自动修改它的,项目打包时也......
  • day08 8.4 Hook重载方法补充
    【一】什么是重载名字一样,但是参数不一样【1】重载介绍在Java中,重载(Overloading)指的是在同一个类中可以定义多个方法(函数)具有相同的名称,但参数列表不同的情况。换句话说,重载允许在同一个类中使用相同的方法名执行不同的操作,提供了更多的灵活性。【2】重载的规则如下:......