• C++Primer第四版13.5.1. 定义智能指针类的例子被new蒙蔽_BLOCK_TYPE_IS_VALID


    ---“不要delete栈上的地址”

    ---“new 和delete是配对的” 的又一个例子

    ---_BLOCK_TYPE_IS_VALID

     

    以下代码是书上实现智能指针类。

    file:HasPtr.h

    #pragma once

    class HasPtr;

    class U_Ptr// private class for use by HasPtr only 

    {

         friend class HasPtr;

         int *ip;

         size_t use;

         U_Ptr(int *p):ip(p),use(1){}

         ~U_Ptr(){delete ip;}           //这里是delete。“不要delete栈上的地址”。

                                                  //ip由p赋值,所以p需要是new出来的,否则...这里delete就会悲剧了。

    };

     

    class HasPtr

    {

    public:

         HasPtr(int *p,int i):ptr(newU_Ptr(p)),ival(i){}//这个new蒙蔽了我的眼睛,误以为任何情况下ip都是new出来的。

                                                                            //其实....这里用new的效果和目的是:在堆上创建U_Ptr对象,获得这个对象的指针,

                                                                           //赋给指针成员ptr,然后在析构的时候delete ptr才是合理的。

                                                                          //是与析构函数中的delete相配对的。

         HasPtr( const HasPtr& ohp):

         ptr(ohp.ptr),ival(ohp.ival){++ptr->use;}

         HasPtr& operator=(const HasPtr& rhp){

                                 ++rhp.ptr->use;

                                 if (--ptr->use == 0){delete ptr;}

                                 ptr=rhp.ptr;

                                 ival = rhp.ival;

                                 return *this;

                                 }

         ~HasPtr(void){

                if (--ptr->use == 0){deleteptr;}

            }

     

             int *get_ptr() const{ return ptr->ip;}

             int get_int() const { return ival;}//

             void set_ptr(int *p){ ptr->ip = p;}

             void set_int(int i){ ival = i;}//

             int get_ptr_val() const { return *ptr->ip;}

             void set_ptr_val(int i) { *ptr->ip = i;}

    private:

              U_Ptr *ptr;

              int ival;

    };

     

    以下是调用测试代码:

    file:main.cpp

    #include <stdlib.h>

    #include "HasPtr.h"

    int main() 

        //悲剧的写法:

           int baseint = 42;//栈上的baseint

           HasPtr obj1( &baseint,10 );   //悲剧,这样传入的实参就是栈上的baseint的地址,delete它是错误的。

        

        //没错的写法:

         int *basep = new int(42); //new出来的,delete  ip时是正确的。

         HasPtr obj1(basep,10);

      HasPtr obj2(obj1);

     

       return EXIT_SUCCESS;

    }

  • 相关阅读:
    项目设计之---------- 模版模式利用
    项目设计之一------简单工厂模式利用
    项目设计之----命令模式的利用
    项目设计之一---------- 代码重构
    项目设计之---------- 类的设计原则
    项目设计之一-------------项目包的设计原则(原)
    模式经验/理解
    Java常量定义需要注意事项及static作用(复习)
    H2数据库使用 详解
    开源数据库 H2, HSQLDB, DERBY, PostgreSQL, MySQL区别/对比图表( 附加翻译) h2数据库
  • 原文地址:https://www.cnblogs.com/riordon/p/3041034.html
Copyright © 2020-2023  润新知