智能指针与类型转换

  • 智能指针的使用
  • 智能指针循环依赖问题
  • 手写智能指针
  • 四种类型转换
    • const_cast
    • static_cast
    • dynmic_cast
    • reinterpreet_cast

智能指针的使用

#include <iostream>
#include <memory> // 智能指针的头文件引入
using namespace std;class Person{public:~Person(){cout << "Person 析构函数" << endl;}
};int mian(){Person * person1 = new Person();//堆区开辟//以前 delete person1; // 现在:shared_ptr<Person> sharedPtr1(person1);// 智能指针帮你释放堆区开辟的--》Person析构函数Person * person2 = new Person();//sharedPtr2 是在栈区开辟的,每添加一个元素 +1 引用计数shared_ptr<Person> sharedPtr2(person2);return 0;
}//main函数弹栈会释放所有的栈成员, sharedPtr1 sharedPtr2 执行对应的析构函数-1

智能指针循环依赖问题

智能指针有循环依赖的问题,要用就用好,不要用的复杂。

#include <iostream>
#include <memory> // 智能指针的头文件引入
using namespace std;// 先声明,让Person1能直接找到Person2,他们相互拥有,函数只能找到在自己之前声明的函数
class Person2; class Person1{public:
shared_ptr<Person2> person2;~Person1(){cout << "Person1 析构函数" << endl;}
};class Person2{public:
shared_ptr<Person1> person1;~Person2(){cout << "Person2 析构函数" << endl;}
};int mian(){Person1 * person1 = new Person1();Person2 * person2 = new Person2();shared_ptr<Person> sharedPtr1(person1); // + 1 计数shared_ptr<Person> sharedPtr2(person2);// + 1 计数cout << "前 sharedPtr1计数是:" << sharedPtr1.use_conut() << endl;cout << "后 sharedPtr2计数是:" << sharedPtr2.use_conut() << endl;// 循环依赖 强引用导致泄露,使用weak_ptr<Person2> person2则不会出现该问题person1->person2 = sharedPtr2;person2->person1 = sharedPtr1;// 计数变成2cout << "前 sharedPtr1计数是:" << sharedPtr1.use_conut() << endl; cout << "后 sharedPtr2计数是:" << sharedPtr2.use_conut() << endl;return 0;
}//main函数弹栈会释放所有的栈成员, sharedPtr1 sharedPtr2 执行对应的析构函数-1

手写智能指针

独占式智能指针,用得比较少,源码里面找了很多都没看到,主要还是shared_ptr

#include <iostream>
#pragma onceusing namespace std;template<typename T>
class Ptr{private:T * object;// 用于指向管理的对象int * count;
public:Ptr(){count = new int(1);object = 0;}Ptr(T * t): Object(T){// 只要你传入对象,那么引用计数为1conut = new int(1);// new 的对象必须是指针接收,new是为了后面操作方便}~Ptr(){// 引用计数减1,为0可以释放对象if (--(*count) == 0) {if (object){delete object;}// 归零delete count;object = 0;count = 0;}}Ptr(const Ptr<T> & p){cout << "拷贝构造函数" << endl;// ptr2 = ptr1++(*p.count);// 当前对象已经被赋值过的情况,再次被赋值,先清空自己。if (--(*count) == 0) {if (object){delete object;}// 归零delete count;object = 0;count = 0;}object = p.object;count = p.count; }// 自定义 = 号运算符重载Ptr<T> & operator = (const Ptr<T> & p) {cout << "= 号运算符重载" << endl;++(*p.count);// 当前对象已经被赋值过的情况,再次被赋值,先清空自己。if (--(*count) == 0) {if (object){delete object;}// 归零delete count;object = 0;count = 0;}object = p.object;count = p.count; return *this;}int use_count(){return *this->count;}
};class Person{}; int mian(){return 0;
}
#include <iostream>
#include <memory> // 智能指针的头文件引入
using namespace std;int mian(){Person * person1 = new Person();Person * person2 = new Person();// 第一种情况Ptr<Person> ptr; // 给自己引用计数 +1 // 第二种情况Ptr<Person> ptr1(person1);// 引用计数 +1
/**
按照正常逻辑:ptr1强引用指向person1,ptr2强引用指向ptr1,
ptr2 = ptr1; 执行拷贝构造函数是我们自己定义的
ptr2也持有了person,因为持有ptr1没有意义,我们的目的是管理对象
person1被ptr1和ptr2都持有了,ptr2计数加1变成2,那么弹栈的时候只有ptr1去销毁person
ptr2是不会销毁的,就不会造成二次重复执行销毁代码
*/// 第三种情况 Ptr<Person> ptr2 = ptr1; // 直接调用拷贝构造函数,不会调用构造函数//注意调用默认无参数构造Ptr<Person> ptr3;// 这种调用的是默认的拷贝函数不是我们自定义的,所以我们要进行=号运算符重载ptr3 = ptr1; // 第四种情况ptr<Person> ptr4(Person);ptr<Person> ptr5(Person);// ptr4先清空自己,要不然原来的person会成为野对象ptr4 = ptr5;return 0;
}//弹栈会调用析构函数

四种类型转换

const_cast

const修饰的都可以转换

#include <iostream>
using namespace std;class Person{public:string name = "default";
};int mian(){const Person * p1 = new Person();//p1->name = "aa"; 常量指针 ,不能修改值Person * p2 = const_cast<Person *>(p1);//将常量指针改成非常量,p2是正常的对象p2->name = "aaa";//修改成功//它实际上多了一个对象p2指向的内存地址跟p1是一样的,p1不能修改,但是p2能改啊!cout << p1->name << endl;//输出aaareturn 0;
}

static_cast

指针相关的(包括子父类)都可以转换

#include <iostream>
using namespace std;class Father{public:void show(){}
};class Son : public Father{public:void show(){}
};int mian(){int n = 88;void * pVoid = &n;int * number = static_cast<int *>(pVoid);cout << *number << endl;// 88 Father * father = new Father;father->show();// static_cast 静态转换看左边(编译器确认)Son * son = static_cast<Son *>(father);son->show(); //son的show输出了delete father;// 回收规则,谁new 就回收 谁return 0;
}

dynmic_cast

动态转换:子父类多态 运行期转换

#include <iostream>
using namespace std;class Father{public:// 动态转换必须让父类成为虚函数virtual void show(){}
};class Son : public Father{public:void show(){}
};int mian(){// 动态转换,在运行期,new Father();已经成定局,所以肯定失败Father * father = new Father();//Father * father = new Son;将上面的代码换成这行代码则就可以,因为: new SonSon * son = dynmic_cast<son *>(father);// 动态转换是有返回值的, null 转换失败if (son) { // != nullcout << "成功" << endl;son->show(); }return 0;
}

reinterpreet_cast

强制转换,比static_cast静态转换强大,静态转换能做的事它都能做。

#include <iostream>
using namespace std;class Player{public:void show(){}
};int mian(){Player * player = new Player;long player1 = reinterpreet_cast<long>(player); // 把对象变成数值// 通过数值变成对象Player * player2 = reinterpreet_cast<Player *>(player1);return 0;
}

C++智能指针与类型转换相关推荐

  1. C++ malloc、智能指针、类型转换等(三)

    文章目录 malloc.calloc.realloc.alloca 智能指针 shared_ptr weak_ptr unique_ptr auto_ptr 强制类型转换 malloc.calloc. ...

  2. rust(66)-rust智能指针与类型转换

  3. C++智能指针:更简单、更高效的内存管理方法

    C++智能指针:从新手到高手的心理密码C++ Smart Pointers: Psychological Passcodes from Beginner to Expert 智能指针简介 (Intro ...

  4. 学习笔记:C++进阶【继承、多态、二叉树进阶、map和set、哈希、C++11、异常、智能指针、特殊类设计、C++的类型转换】

    文章目录 前言 一.继承 1. 继承的概念及定义 1.1 继承的概念 1.2 继承的定义 1.2.1 定义格式 1.2.2 继承关系和访问限定符 1.2.3 继承基类成员访问方式的变化 2. 基类和派 ...

  5. C++之智能指针、强制类型转换

    智能指针 头文件:#include <memory> C++ 98 std::auto_ptr<std::string> ps (new std::string(str)): ...

  6. C++ 智能指针(unique_ptr / shared_ptr)代码实现

    文章目录 unique_ptr 智能指针的实现 shared_ptr 智能指针的实现 指针类型转换 unique_ptr 智能指针的实现 一个对象只能被单个unique_ptr 所拥有. #inclu ...

  7. 【Smart_Point】C/C++ 中智能指针

    C++11智能指针 目录 C++11智能指针 1.1 C++11智能指针介绍 1.2 为什么要使用智能指针 1.2.1 auto_ptr(C++98的方案,C++11已经抛弃)采用所有权模式. 1.2 ...

  8. Boost智能指针——shared_ptr

    boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限.顾名思义,boost::shared_ptr是可以 ...

  9. Boost学习笔记-智能指针

    1.  智能指针 scoped_ptr 只在作用域内生效,离开作用域既释放资源,不能复制和赋值.类似于标准库的auto_ptr,但它相对于auto_ptr的优势在于,他的要求更严格,使用起来更安全.a ...

  10. [C++11]弱引用智能指针weak_ptr初始化和相关的操作函数

    弱引用智能指针 std::weak_ptr 可以看做是 shared_ptr 的助手,它不管理 shared_ptr 内部的指针.std::weak_ptr 没有重载操作符 * 和 ->,因为它 ...

最新文章

  1. 中date转为string_股票数据获取篇(持续更新中...)
  2. Eclipse和MyEclipse 手动设置 Java代码 注释模板
  3. html 5 gif手机版,动画GIF在HTML5画布
  4. 【CyberSecurityLearning 42】日志记录规则
  5. 修改TOMCAT的JVM虚拟机内存大小几种方式
  6. Switchhosts软件安装包
  7. UML用例图分析——铁路售票系统
  8. Java之父评价C语言之父,Java之父评价C语言之父:C语言撑起了一切
  9. 【PANet】《Path Aggregation Network for Instance Segmentation》
  10. ELDER-RAY (多头力度和空头力度)
  11. [GKCTF 2021]excel 骚操作
  12. git的一些撤销/回退操作
  13. QTableWidget表格控件的用法
  14. 1-交通数据的获取系列学习
  15. 斯坦福神经调控疗法(Stanford Neuromodulation Therapy, SNT)
  16. Odoo产品分析 (三) -- 人力资源板块(3) -- 休假管理(1)
  17. 2017语义分割综述
  18. ubuntu16.04对SD卡进行分区
  19. Python 一个抓取糗百的段子的小程序
  20. 斐讯K3路由器查看内存类型

热门文章

  1. 定义Java中的方法及调用
  2. BZOJ 3505: [Cqoi2014]数三角形|组合数学
  3. Workgroup 协议
  4. mysql 查看 脏页_MySQL:刷脏页
  5. pyinstaller包含html文件,pyinstaller打包exe
  6. java SE部分以及数据库学习笔记
  7. 【点宽专栏】研报复现——跨期价差分析与跨期套利研究
  8. 计算机未检测到任何网络硬件,win10系统连不上网提示“检测不到任何网络硬件”怎么办...
  9. ESP8266最小系统
  10. C++面向对象程序设计——简单的商品销售题