#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的更多相关文章

  1. C++中智能指针的设计和使用

    转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7561235 智能指针(smart pointer)是存储指向动态分配(堆 ...

  2. 不可不表的OSG智能指针之强指针与弱指针 《转载》

    不可不表的OSG智能指针之强指针与弱指针 <转载> 使用OSG的人都知道OSG的内存管理方式采用了智能指针,通过智能指针的方式让OSG自己处理对象的销毁工作.在OSG中有两个智能指针类型, ...

  3. 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱

    必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针.         在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...

  4. C++11 unique_ptr智能指针详解

    在<C++11 shared_ptr智能指针>的基础上,本节继续讲解 C++11 标准提供的另一种智能指针,即 unique_ptr 智能指针. 作为智能指针的一种,unique_ptr ...

  5. 转:C++ 智能指针的正确使用方式

    转:https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/#comments C++11 中推出了三种智能指针,uniq ...

  6. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  7. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  8. C++11 智能指针

    C++ 11标准库引入了几种智能指针 unique_ptr shared_ptr weak_ptr C++内存管理机制是当一个变量或对象从作用域过期的时候就会从内存中将他干掉.但是如果变量只是一个指针 ...

  9. C++智能指针简单剖析

    导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题 ...

随机推荐

  1. IntelliJ IDEA注册码

    1.打开IJ,help选项下的register 2. 选择Activation code 将注册码粘到内容框里,点击ok即可 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QT ...

  2. ios--个人资料修改

    点击进行编辑  (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *) ...

  3. WinForm实现对权限菜单进行管理

    一.界面: 二.数据库访问类: public class DataClass { private readonly string connect = ConfigurationManager.AppS ...

  4. 《The Evolution of Lua》读书笔记 1

    lua的优点: 可移植性 容易嵌入 体积小 高效率 这些优点都来自于lua的设计目标:简洁.从Scheme获得了很多灵感,包括匿名函数,合理的语义域概念   lua前身: 巴西被禁运,引入计算机软件和 ...

  5. Array(数组)--map方法

    关于Array.prototype.map() MDN 给的定义是: 在作用数组元素的每一项上调用一个方法(callback),返回一个新数组: 使用格式:arr.map(callback[,this ...

  6. Linux删除apt-get安装的软件

    我们都知道安装软件最简单的方法是apt-get install,但是卸载就不常用了,如何卸载呢?1.sudo apt-get remove xxxxxsudo apt-get autoremove2. ...

  7. 转:对于服务器AdminServer, 与计算机Machine-0相关联的节点管理器无法访问

    控制台启动server时报"对于服务器server-1与计算机machin<!--StartFragment -->对于服务器AdminServer, 与计算机Machine-0 ...

  8. Linux测试环境部署jdk(一)

    安装配置JDK yum install -y lrzsz  安装rz,方便xshell上传下载文件 Jdk: jdk-6u1-linux-i586 Tomcat: apache-tomcat-7.0. ...

  9. IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic、 @synthesize、@property、@dynamic

    IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic.                     @synth ...

  10. input中加入搜索图标

    刚吃了一份宫保鸡丁刀削面,幸福感满满,写篇博客消耗一下热量. 今天工作遇到的一个问题是在input输入框中加入图标,当输入内容后,图标和提示语一起隐藏,类似于placeholder的功能.如淘宝页面, ...