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() {}
~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 == ) delete ptr; }
private:
U_Ptr *ptr;
int val;
}; HasPtr& HasPtr::operator=(const HasPtr &orig)
{
++orig.ptr->use;
if(--ptr->use == )
delete ptr;
ptr = orig.ptr;
val = orig.val;
return *this;
} int main()
{
int i = , j = ;
int *p = new int();
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 = , j = ;
HasPtr hasptr(i, j);
HasPtr hasptr2(hasptr);
hasptr2 = hasptr;
}

【c++】类管理指针成员的更多相关文章

  1. C++ Primer 学习笔记_57_类和数据抽象 --管理指针成员

    复印控制 --管理指针成员 引言: 包括指针的类须要特别注意复制控制.原因是复制指针时.一个带指针成员的指针类 class HasPtr { public: HasPtr(int *p,int i): ...

  2. C++ Primer 有感(管理类的指针成员)

    C++类的指针成员与其他成员有所不同,指针成员指向一个内存地址,该地址的内存需要我没管理. 我现在分析一下为什么要管理指针成员. 有如下Student类,Student.h如下: [cpp] view ...

  3. C++管理指针成员

    1.C++中一般採用以下三种方法之中的一个管理指针成员: (1)指针成员採取常规行为. 这种类具有指针的全部缺陷:具有指针成员且使用默认复制构造函数和赋值操作符,无法避免悬垂指针(两个对象的指针成员指 ...

  4. C++ 带有指针成员的类处理方式

    在一个类中,如果类没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存.但是如果一个类带了指针成员,那么需要我们自己来写一个析构函数来管理内存.在<<c++ primer&g ...

  5. 类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)

    假设我们要设计一个包含以下操作的 Sales_data 类: 1.一个 isbn 成员函数,用于返回对象的 book_no 成员变量 2.一个 combine 成员函数,用于将一个 Sales_dat ...

  6. YTU 2636: B3 指向基类的指针访问派生类的成员函数

    2636: B3 指向基类的指针访问派生类的成员函数 时间限制: 1 Sec  内存限制: 128 MB 提交: 433  解决: 141 题目描述 领导类(Leader)和工程师类(Engineer ...

  7. 15.含有指针成员的类的拷贝[ClassCopyConstructorWithPointerMember]

    [题目] 下面是一个数组类的声明与实现.请分析这个类有什么问题,并针对存在的问题提出几种解决方案.  C++ Code  123456789101112131415161718192021222324 ...

  8. (转)MFC中获得各个类的指针/句柄 ID的总结

    http://www.cnblogs.com/ylhome/archive/2009/10/06/1578478.html 一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard ...

  9. MFC中获取App,MainFrame,Doc和View类等指针的方法

    From: http://hi.baidu.com/wxnxs/item/156a68f5b3b4ed18e3e3bd03   MFC中获取App,MainFrame,Doc和View类等指针的方法 ...

随机推荐

  1. Android-Activity-startActivityForResult

    之前 Android-Intent意图传递数据,的博客讲解了,一个Activity 跳转 到另外一个Activity 可以把数据带过去 Android还提供了一种方式,一个Activity 跳转 到另 ...

  2. Java50道经典习题-程序1 不死神兔

    题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 分析:假如:1月1日有1对兔子,根据题目“从出生后 ...

  3. stderr和stdout(printf、fprintf、sprintf)(转)

    本文转自:http://www.cnblogs.com/zhangyabin---acm/p/3203745.html 先区分一下:printf,sprintf,fprintf. 1,printf就是 ...

  4. BZOJ 1562 [NOI2009] 变换序列

    [NOI2009] 变换序列 [题解] 就是有一个序列,每个位置可以填两个数,不可重复,问最小字典序. 显然,可以建一个二分图,判合法就是找完美匹配. 那怎么弄最小字典序呢?有好多种解法,我这里给出了 ...

  5. codeforces|CF13C Sequence

    大概的题意就是每次可以对一个数加一或者减一,然后用最小的代价使得原序列变成不下降的序列. 因为是最小的代价,所以到最后的序列中的每个数字肯定在原先的序列中出现过.(大家可以想一下到底是为什么,或者简单 ...

  6. OCP 052题库全变,最新052考试题及答案整理-第11题

    11.Which three are true about UNDO data? A) It is used to roll back failed transactions. B) It is us ...

  7. BZOJ.5407.girls/CF985G. Team Players(三元环计数+容斥)

    题面 传送门(bzoj) 传送门(CF) \(llx\)身边妹子成群,这天他需要从\(n\)个妹子中挑出\(3\)个出去浪,但是妹子之间会有冲突,表现为\(i,j\)之间连有一条边\((i,j)\), ...

  8. python 序列结构-列表,元组,字典,字符串,集合

    列表 """ name_list.__add__( name_list.__getslice__( name_list.__new__( name_list.append ...

  9. json "key" 注意

    json 的key只能是字符串 必须使用 双引号

  10. 963 AlvinZH打怪刷经验(背包DP大作战R)

    963 AlvinZH打怪刷经验 思路 这不是一道普通的01背包题.大家仔细观察数据的范围,可以发现如果按常理来的话,背包容量特别大,你也会TLE. 方法一:考虑01背包的一个常数优化----作用甚微 ...