c++智能指针实现方式1
#include<iostream>
using namespace std; // 定义仅由HasPtr类使用的U_Ptr类,用于封装使用计数和相关指针
// 这个类的所有成员都是private,我们不希望普通用户使用U_Ptr类,所以它没有任何public成员
// 将HasPtr类设置为友元,使其成员可以访问U_Ptr的成员
class U_Ptr
{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p) : ip(p) , use()
{
cout << "U_ptr constructor called !" << endl;
}
~U_Ptr()
{
delete ip;
cout << "U_ptr distructor called !" << endl;
}
}; class HasPtr
{
public:
// 构造函数:p是指向已经动态创建的int对象指针
HasPtr(int *p, int i) : ptr(new U_Ptr(p)) , val(i)
{
cout << "HasPtr constructor called ! " << "use = " << ptr->use << endl;
} // 复制构造函数:复制成员并将使用计数加1
HasPtr(const HasPtr& orig) : ptr(orig.ptr) , val(orig.val)
{
++ptr->use;
cout << "HasPtr copy constructor called ! " << "use = " << ptr->use << endl;
} // 赋值操作符
HasPtr& operator=(const HasPtr&); // 析构函数:如果计数为0,则删除U_Ptr对象
~HasPtr()
{
cout << "HasPtr distructor called ! " << "use = " << ptr->use << endl;
if (--ptr->use == )
delete ptr;
} // 获取数据成员
int *get_ptr() const
{
return ptr->ip;
}
int get_int() const
{
return val;
} // 修改数据成员
void set_ptr(int *p) const
{
ptr->ip = p;
}
void set_int(int i)
{
val = i;
} // 返回或修改基础int对象
int get_ptr_val() const
{
return *ptr->ip;
}
void set_ptr_val(int i)
{
*ptr->ip = i;
}
private:
U_Ptr *ptr; //指向使用计数类U_Ptr
int val;
};
HasPtr& HasPtr::operator = (const HasPtr &rhs) //注意,这里赋值操作符在减少做操作数的使用计数之前使rhs的使用技术加1,从而防止自我赋值
{
// 增加右操作数中的使用计数
++rhs.ptr->use;
// 将左操作数对象的使用计数减1,若该对象的使用计数减至0,则删除该对象
if (--ptr->use == )
delete ptr;
ptr = rhs.ptr; // 复制U_Ptr指针
val = rhs.val; // 复制int成员
return *this;
} int main(void)
{
int *pi = new int();
HasPtr *hpa = new HasPtr(pi, ); // 构造函数
HasPtr *hpb = new HasPtr(*hpa); // 拷贝构造函数
HasPtr *hpc = new HasPtr(*hpb); // 拷贝构造函数
HasPtr hpd = *hpa; // 拷贝构造函数 cout << hpa->get_ptr_val() << " " << hpb->get_ptr_val() << endl;
hpc->set_ptr_val();
cout << hpa->get_ptr_val() << " " << hpb->get_ptr_val() << endl;
hpd.set_ptr_val();
cout << hpa->get_ptr_val() << " " << hpb->get_ptr_val() << endl;
delete hpa;
delete hpb;
delete hpc;
cout << hpd.get_ptr_val() << endl;
return ;
}
来自http://blog.csdn.net/hackbuteer1/article/details/7561235
智能指针是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄漏。它的一种通用实现技术使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享一个同一个指针。每次创建类的新对象时,
1,初始化指针并将引用计数置为1;
2,当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
3,对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;
4,调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
智能指针重载了->和*操作符;
能自动销毁。主要是利用栈对象的有限作用域以及临时对象(有限作用域实现),使用析构函数释放内存。
当然,还包括复制时可以修改源对象等。
智能指针根据需求不同,设计也不同(写时复制,赋值即释放对象拥有权限、引用计数等,控制权转移等)。auto_ptr
即是一种常见的智能指针。
智能指针的通用模板:
template <class T>
class smartpointer{
private:
T *_ptr;
public:
smartpointer(T *p): _ptr(p){
}
T& operator *(){return *_ptr;}
T* operator → (){return _ptr;}
~smartpointer(){delete _ptr;}
};
实现引用计数的策略,两种的一种:
// 定义仅由HasPtr类使用的U_Ptr类,用于封装使用计数和相关指针
//
这个类的所有成员都是private,我们不希望普通用户使用U_Ptr类,所以它没有任何public成员
// 将HasPtr类设置为友元,使其成员可以访问U_Ptr的成员
class U_Ptr
{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p) : ip(p) , use(1)
{
cout << "U_ptr constructor called
!" << endl;
}
~U_Ptr()
{
delete ip;
cout << "U_ptr distructor called
!" << endl;
}
};
HasPtr类需要一个析构函数来删除指针。但是,析构函数不能无条件的删除指针。”
条件就是引用计数。如果该对象被两个指针所指,那么删除其中一个指针,并不会调用该指针的析构函数,因为此时还有另外一个指针指向该对象。看来,智能指针主要是预防不当的析构行为,防止出现悬垂指针。
包含指针的类需要特别注意复制控制,原因是复制指针时只复制指针中的地址,而不是复制指针指向的对象。
c++管理指针成员的三种方法之一:
利用一个辅助类来管理指针的复制。原来的类中有一个指针指向辅助类,辅助类的数据成员是一个计数器和一个指针(指向原来的)(此为本次智能指针实现方式)。
c++智能指针实现方式1的更多相关文章
- C++中智能指针的设计和使用
转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7561235 智能指针(smart pointer)是存储指向动态分配(堆 ...
- 不可不表的OSG智能指针之强指针与弱指针 《转载》
不可不表的OSG智能指针之强指针与弱指针 <转载> 使用OSG的人都知道OSG的内存管理方式采用了智能指针,通过智能指针的方式让OSG自己处理对象的销毁工作.在OSG中有两个智能指针类型, ...
- 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱
必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针. 在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...
- C++11 unique_ptr智能指针详解
在<C++11 shared_ptr智能指针>的基础上,本节继续讲解 C++11 标准提供的另一种智能指针,即 unique_ptr 智能指针. 作为智能指针的一种,unique_ptr ...
- 转:C++ 智能指针的正确使用方式
转:https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/#comments C++11 中推出了三种智能指针,uniq ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- 基于C/S架构的3D对战网络游戏C++框架_05搭建系统开发环境与Boost智能指针、内存池初步了解
本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...
- C++11 智能指针
C++ 11标准库引入了几种智能指针 unique_ptr shared_ptr weak_ptr C++内存管理机制是当一个变量或对象从作用域过期的时候就会从内存中将他干掉.但是如果变量只是一个指针 ...
- C++智能指针简单剖析
导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题 ...
随机推荐
- poj1741 (点分治)
Problem Tree 题目大意 给一棵树,有边权.求树上距离小于等于K的点对有多少. 解题分析 点分治.对每一棵子树进行dfs,求出每棵子树的重心,继而转化为子问题. 对于经过根的路径i--j,令 ...
- Centeros7 环境相关问题
服务处理命令 systemctl start mariadb #启动MariaDB systemctl stop mariadb #停止MariaDB systemctl restart mariad ...
- PHPnow在win8下安装失败的解决办法
提示: 安装服务[ Apache_pn ]失败,可能原因如下:1.服务名已存在,请卸载或使用不同服务名.2.非管理员权限,不能操作Window NT服务. 解决方案: 搜索:命令提示符 , 右键以 ...
- 传智播客JavaWeb day11--事务的概念、事务的ACID、数据库锁机制、
1. 什么叫做事务? 2.默认情况下每一条sql语句都是一个事务,然后自动提交事务 ps:如果想多条语句占一个事务,则可以手动设置SetAutoCommit为false 3.关键字 start tr ...
- iOS 源代码管理工具之SVN
源代码管理工具之SVN 源代码管理工具SVN是一款非常强大的源代码管理工具,现在国内70%-90%的公司都在使用SVN来管理源代码,下面就让小编给大家着重介绍一下SVN的使用,SVN的使用主要分为下面 ...
- JDBC的作用及重要接口
JDBC是由一系列连接(Connection).SQL语句(Statement)和结果集(ResultSet)构成的,其主要作用概括起来有如下3个方面: 建立与数据库的连接. 向数据库发起 ...
- 优化 UltraEdit 打开大文件时的性能
UltraEdit 原本就是被设计成可以打开超大文件的工具,只不过在默认情况下需要进行以下优化设置: 禁止临时文件 禁止显示行号 禁止文件(回车 & 换行符)转换 禁止代码折叠 禁止显示函数列 ...
- CLR via C# 3rd - 05 - Primitive, Reference, and Value Types
1. Primitive Types Any data types the compiler directly supports are called primitive types. ...
- 接口 Post
public static StringBuilder HttpPost(string Url, byte[] Postdata, string i) { StringBuilder content ...
- Adobe After Effects工程使用aep格式来存储
写页面的时候发现好几处的按钮都是这种样式,于是把这个按钮的样式单独提取出来放着全局css文件中 .base-btn { display: block; width: 90%; height: 54px ...