提领NULL指针
通常之中导致程序崩溃的最重要的原因是试图取消引用NULL指针。正如在以前的文章中指出,智能指针RefCountPtr和ScopedPtr它提供了一个诊断的执行时间。
但,并不是所有的指针是所有的对象都一个智能指针。此为了对试图解引用一个不具有对象全部权的指针的行为进行诊断,引入一种并不删除它所指向的对象的“半智能”指针。比如,例如以下代码演示样例:
template <typename T>
class Ptr
{
public:
explicit Ptr(T* p = NULL)
: ptr_(p)
{
} T* Get() const
{
return ptr_;
} Ptr<T>& operator=(T* p)
{
ptr_ = p;
return *this;
} T* operator->() const
{
SCPP_TEST_ASSERT(ptr_ != NULL,
"Attempt to use operator -> on NULL pointer.");
return ptr_;
} T& operator*() const
{
SCPP_TEST_ASSERT(ptr_ != NULL,
"Attempt to use operator * on NULL pointer.");
return *ptr_;
} private:
T* ptr_; };
虽然出现了操作符=。但它并非告诉编译器当我们试图把一个Ptr<T>赋值给还有一个Ptr<T>时该怎么做的赋值符。假设我们为这个类编写一个赋值操作符。它应该被声明为例如以下这样的形式:
Ptr<T>& operator=(const Ptr<T>& that);
注意在前面这个类中,操作符=具有不同的签名:它的右边有一个原始指针p。因此,这个类让编译器为Ptr<T>创建拷贝构造函数和复制操作符。
因为Ptr<T>类的拷贝构造函数和赋值操作符都是同意出现的,因此,我们能够自由复制这些指针,或者把它们作为函数的返回值等。
第二种情况。如果建议我们用Ptr<T>取代T*,对于const T*指针该使用什么?答案为:Ptr<const T>。
如果例如以下的这个类:
class MyClass
{
public:
explicit MyClass(int id)
: id_(id)
{
} int GetId() const
{
return id_;
} void SetId(int id)
{
id_ = id;
} private:
int id_;
};
假设想创建一个行为与const MyClass*相似的半智能指针。仅仅能像以下的做法一样:
scpp::Ptr<const MyClass> p(new MyClass(1));
cout<<"Id = "<<p->GetId()<<endl; //可以编译并执行
p->SetId(666); //无法通过编译
注意,试图通过这个指针调用一个很量函数将将无法通过编译。这意味着它正确的表现了常量指针的行为。
对于Ptr<T>模板指针具有下面特性:
(1)它并不拥有它所指向的对象的全部权,应该作为同样情况下原始指针的替代品;
(2)它默认被初始化为NULL;
(3)它提供了执行时诊断。当它本身为NULL时,假设对它进行调用,就能够对这样的行为进行检測。
小结:
- 假设指针拥有它所指向的对象的全部权,就使用智能指针
- 假设是不拥有所指向的对象的全部权的原始指针T*。就用模板类Ptr<T>取而代之
- 对于常量指针(cosnt T*)。使用Ptr<cosnt T>
提领NULL指针的更多相关文章
- NULL指针、零指针、野指针
1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ...
- void指针、NULL指针和未初始化指针
一个指针可以被声明为void类型,比如void *x.一个指针可以被赋值为NULL.一个指针变量声明之后但没有被赋值,叫做未初始化指针. 1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...
- 野指针、NULL指针和void*
一.野指针 “野指针”不是NULL指针,是指向“垃圾”内存的指针. “野指针”的成因主要有三种: (1)指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱 ...
- NULL指针 Void* 和野指针
在C和C++的语言中常常有这几个概念: NULL指针.空指针.Void *指针.野指针(Wild Pointer)甚至垂悬指针(Dangling Pointer). 1.NULL指针,一般用于指向一个 ...
- Null指针
C++ Null 指针 C++ 指针 C++ 指针 在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯.赋为 NULL 值的指针被称为空指针. NULL ...
- 为什么NULL指针也能访问成员函数?(但不能访问成员变量)
查看更加详细的解析请参考这篇文章:http://blog.51cto.com/9291927/2148695 看一个静态绑定的例子: 1 #include <iostream> 2 3 u ...
- 空指针、NULL指针、零指针
1. 空指针.NULL指针.零指针 1.1 什么是空指针常量 0.0L.'\0'.3 - 3.0 * 17 (它们都是“integer constant expression”)以及 (void*)0 ...
- NULL指针引起的一个linux内核漏洞
NULL指针一般都是应用于有效性检测的,其实这里面有一个约定俗成的规则,就是说无效指针并不一定是 NULL,只是为了简单起见,规则约定只要指针无效了就将之设置为NULL,结果就是NULL这个指针被用来 ...
- void指针和NULL指针
Void指针和NULL指针 Void指针: Void指针我们称之为通用指针,就是可以指向任意类型的数据.也就是说,任何类型的指针都可以赋值给Void指针. 举例: #include<stdio. ...
随机推荐
- 试解析Tomcat运行原理(一)--- socket通讯(转)
关于这篇文章也确实筹划了很久,今天决定开篇写第一篇,说起tomcat首先很容易联想到IIS,因为我最开始使用的就是.net技术,我第一次使用asp写学生成绩管理系统后,很茫然如何让别人都能看到或者说使 ...
- 【Demo 0009】Android 组件(BroadcastReceiver)
本章学习要点: 1. 了解Broadcast的作用; 2. 掌握自定义广播和系统广播的接收: 3. 掌握广播的发送:
- crm使用FetchXml聚合查询
/* 创建者:菜刀居士的博客 * 创建日期:2014年07月08号 */ namespace Net.CRM.FetchXml { using System; using Micr ...
- 第13章、布局Layouts之RelativeLayout相对布局(从零開始学Android)
RelativeLayout相对布局 RelativeLayout是一种相对布局,控件的位置是依照相对位置来计算的,后一个控件在什么位置依赖于前一个控件的基本位置,是布局最经常使用,也是最灵活的一种布 ...
- Effective C++_笔记_条款03_尽可能使用const
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 关键字const多才多艺,语法变化多端.关于const的基本用法 ...
- 14.9 InnoDB Row Storage and Row Formats InnoDB 行存储和行格式:
14.9 InnoDB Row Storage and Row Formats InnoDB 行存储和行格式: 14.9.1 Overview of InnoDB Row Storage 14.9.2 ...
- 医院API免费接口的公布
医院通网(http://hospital.yi18.net) 站点上站快两个月了,基本已经稳定,尽管还有非常多小bug,但还是不影响大局.抱着数据开放和共享的理念,医院大全API接口 (http:// ...
- 开始AFNetworking
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助.欢迎给作者捐赠.支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 This ...
- Android API中被忽略的几个函数接口
1. MotionEvent的几个函数 下面的方法都支持多点触摸,即可以对单个触摸点调用下面的方法 1.1 getPressure() 这个api 可以获取到手指触摸屏幕时候的压力,但是需要硬件和驱动 ...
- 【OpenMesh】Some basic operations: Flipping and collapsing edges
这一节中你将学到一些OpenMesh中早已提供的基础操作. 内容包括三角形网格边的翻转以及通过连接邻接的顶点边缘折叠. 三角形网格的翻转(Flipping edges) 考虑到两个邻接面的三角形网格中 ...