zoukankan      html  css  js  c++  java
  • 提领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>




  • 相关阅读:
    Redis过期key是怎么样清理的?----互联网大厂面试题
    Docker容器引擎使用教程
    区块链算法
    MYSQL 常用语句与函数命令
    漏洞利用:验证绕过,XSS利用,Cookic盗用,文件上传
    小白网工入行要具备哪些基本技能?
    VMware中乌班图安装VMtools步骤
    防火墙技术原理-思维导图
    JAVA学习第一课-手工笔记
    DOS(磁盘操作系统)基本命令-思维导图
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5035004.html
Copyright © 2011-2022 走看看