C++管理指针成员
1、C++中一般採用以下三种方法之中的一个管理指针成员:
(1)指针成员採取常规行为。
这种类具有指针的全部缺陷:具有指针成员且使用默认复制构造函数和赋值操作符,无法避免悬垂指针(两个对象的指针成员指向同一内存。删除了当中一个指针指向的内存时,还有一个指针将不再指向有效的内存空间)。
(2)类能够实现所谓的"智能指针"行为。引入计数类,智能指针类将一个计数器与类的对象相关联。使用计数跟踪该类有多少个对象共享同一指针。当计数为0时。删除对象。
(3)类採取值行为。採用重载的复制构造函数、赋值操作符和析构函数。
2、指针成员採取常规行为演示样例:两个指针指向同一块内存,会引起不可预料的后果
- #include "stdafx.h"
- #include <string.h>
- #include <iostream.h>
- class HasPtr
- {
- public:
- HasPtr(int *p,int i):ptr(p),val(i){}
- int *get_ptr()const{return ptr;}
- int get_val()const{return val;}
- void set_ptr(int *p){ptr=p;}
- void set_val(int i){val=i;}
- int get_ptr_val()const{return *ptr;}
- void set_ptr_val(int val)const{*ptr=val;}
- private:
- int *ptr;
- int val;
- };
- int main(int argc, char* argv[])
- {
- int *p=new int(10);
- cout<<p<<endl;
- HasPtr ptr(p,10);
- cout<<ptr.get_ptr()<<endl;
- delete p;
- cout<<ptr.get_ptr_val()<<endl; //p和ptr中的指针指向同一对象。删除该对象后,ptr中的指针不再指向有效的对象。
- return 0;
- }
3、"智能指针"行为演示样例:注意构造函数
- #include "stdafx.h"
- #include <string.h>
- #include <iostream.h>
- class HasPtr;
- //计数类U_Ptr全部成员均为private,将HasPtr设置为计数类的友元类,使其能够訪问U_Ptr的成员
- class U_Ptr
- {
- friend class HasPtr;
- int *ip;
- size_t use;
- U_Ptr(int *p):ip(p),use(1){}
- ~U_Ptr()
- {
- delete ip;
- }
- };
- class HasPtr
- {
- public:
- HasPtr(int *p,int i):ptr(new U_Ptr(new int(*p))),val(i){} //构造函数,创建新的U_Ptr对象
- HasPtr(const HasPtr &orig):ptr(orig.ptr),val(orig.val){++ptr->use;} //复制构造函数,计数加1
- HasPtr& operator=(const HasPtr &rhs) //赋值操作符,左操作数计数减1,右操作数计数加1,假设左操作数减至0,则删除左操作数指向的对象
- {
- if (this!=&rhs)
- {
- ++rhs.ptr->use;
- if(--ptr->use==0)
- delete ptr;
- ptr=rhs.ptr;
- val=rhs.val;
- }
- return *this;
- }
- ~HasPtr() //析构函数,计数减1,假设计数减至0,就删除对象
- {
- if (--ptr->use==0)
- {
- delete ptr;
- }
- }
- int *get_ptr()const{return ptr->ip;}
- int get_val()const{return val;}
- void set_ptr(int *p){ptr->ip=p;}
- void set_val(int i){val=i;}
- int get_ptr_val()const{return *ptr->ip;}
- void set_ptr_val(int val){*ptr->ip=val;}
- private:
- U_Ptr *ptr;
- int val;
- };
- int main(int argc, char* argv[])
- {
- int *p=new int(10);
- cout<<p<<endl;
- HasPtr ptr(p,10);
- cout<<ptr.get_ptr()<<endl; //两指针指向同一块内存
- cout<<ptr.get_ptr_val()<<endl;
- delete p;
- return 0;
- }
4、定义值型类:三法则(赋值操作符、复制构造函数、析构函数)
- #include <string.h>
- #include <iostream.h>
- class HasPtr
- {
- public:
- HasPtr(int *p,int i):ptr(new int(*p)),val(i){} //构造函数
- HasPtr(const HasPtr &orig):ptr(new int(*orig.ptr)),val(orig.val){} //复制构造函数
- HasPtr& operator=(const HasPtr &rhs) //赋值操作符
- {
- if (this!=&rhs)
- {
- ptr=new int(*rhs.ptr);
- val=rhs.val;
- }
- return *this;
- }
- ~HasPtr(){delete ptr;} //析构函数
- int *get_ptr()const{return ptr;}
- int get_val()const{return val;}
- void set_ptr(int *p){ptr=p;}
- void set_val(int i){val=i;}
- int get_ptr_val()const{return *ptr;}
- void set_ptr_val(int val)const{*ptr=val;}
- private:
- int *ptr;
- int val;
- };
- int main(int argc, char* argv[])
- {
- int *p=new int(10);
- cout<<p<<endl;
- HasPtr ptr(p,10);
- cout<<ptr.get_ptr()<<endl; //p与ptr的指针不是指在同一块内存,可是所指向的对象内容是一样的
- delete p;
- cout<<ptr.get_ptr_val()<<endl;
- return 0;
- }
C++管理指针成员的更多相关文章
- C++ Primer 学习笔记_57_类和数据抽象 --管理指针成员
复印控制 --管理指针成员 引言: 包括指针的类须要特别注意复制控制.原因是复制指针时.一个带指针成员的指针类 class HasPtr { public: HasPtr(int *p,int i): ...
- 【c++】类管理指针成员
c++编程提倡使用标准库,一个原因是标准库大胆减少对指针的使用.但是许多程序是离不开指针的.包含指针的类需要特别注意复制控制,原因是复制指针时只复制指针中的地址,而不复制指针所指向的对象.这样当把一个 ...
- C++ Primer 有感(管理类的指针成员)
C++类的指针成员与其他成员有所不同,指针成员指向一个内存地址,该地址的内存需要我没管理. 我现在分析一下为什么要管理指针成员. 有如下Student类,Student.h如下: [cpp] view ...
- C++ 带有指针成员的类处理方式
在一个类中,如果类没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存.但是如果一个类带了指针成员,那么需要我们自己来写一个析构函数来管理内存.在<<c++ primer&g ...
- 关于Vector中的元素中含有指针成员的情况
对于容器,当容器的各个元素为类类型,且该类类型中含有指针成员时: 如果类类型的析构函数中包含了对指针变量指向内存的释放操作,则在利用clear()函数删除容器所有元素时,会自动调用类的析构函数,自动实 ...
- 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体
1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...
- C++对象的复制——具有指针成员的类的对象的复制
//smartvessel@gmail.com class Table{ Name * p; size_t sz; publish: Table(size_t s = 15){p = new Name ...
- C++函数指针相关 & 类成员的指针 & 成员函数的指针
有时候会有指向类成员变量或者成员函数的指针,但是注意,这个指针并不是针对一个地址的指向,而更多的是一个偏移. 同时,支持将父类对象的成员 转为 子类对象的成员指针,如下: 反过来,是不行的.因为父类的 ...
- 15.含有指针成员的类的拷贝[ClassCopyConstructorWithPointerMember]
[题目] 下面是一个数组类的声明与实现.请分析这个类有什么问题,并针对存在的问题提出几种解决方案. C++ Code 123456789101112131415161718192021222324 ...
随机推荐
- Django day15 (二) csrf的 跨站请求伪造 与 局部禁用 , 局部使用
一: csrf 的跨站请求伪造 二: csrf 的局部禁用 , 局部使用
- ACM_Exponentiation
Exponentiation Time Limit: 2000/1000ms (Java/Others) Problem Description: Problems involving the com ...
- 多文件上传ajax jquery
jquery的ajaxSubmit()和多文件上传 <%@ page language="java" import="java.util.*" pageE ...
- HTTPS的中那些加密算法
密码学在计算机科学中使用非常广泛,HTTPS就是建立在密码学基础之上的一种安全的通信协议.HTTPS早在1994年由网景公司首次提出,而如今在众多互联网厂商的推广之下HTTPS已经被广泛使用在各种大小 ...
- Android6.0以上版本获取本机蓝牙地址
Android6.0以上版本使用BluetoothAdapter.getDefaultAdapter().getAddress()是获取不到正确的蓝牙地址的,返回的值都是02:00:00:00:00: ...
- uva11205 The broken pedometer 子集生成
PS:此题我在网上找了很久的题解,发现前面好多题解的都是没有指导意义的.后来终于找到了一篇好的题解. 好的题解的链接:http://blog.csdn.net/u013382399/article/d ...
- DeltaFish 校园物资共享平台 第三次小组会议
一.想法 娄雨禛: 网页底层开发转移到后端,快速建站,效率高. 可以依照模板进行仿制. 可以考虑只进行页面设计. 但是出现问题不会调试. 所以自己写源码,做出一个大致的样子. 二.上周进度汇报 齐天杨 ...
- spring - quartz - experssion 表达式
字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN- ...
- 【sqli-labs】 less16 POST - Blind- Boolian/Time Based - Double quotes (基于bool型/时间延迟的双引号POST型盲注)
' or 1=1# -->失败 1" or 1=1# -->失败 1') or 1=1# -->失败 1") or 1=1# -->成功 判断为双引号变形注 ...
- SQL第二节课
SQL练习题 一. 设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的 ...