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

    }

  • 相关阅读:
    K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院
    [Noi2015]软件包管理器 BZOJ4196
    [SDOI2011]染色 BZOJ2243 树链剖分+线段树
    序列操作 BZOJ2962 线段树
    斜率优化入门学习+总结 Apio2011特别行动队&Apio2014序列分割&HZOI2008玩具装箱&ZJOI2007仓库建设&小P的牧场&防御准备&Sdoi2016征途
    BZOJ1854: [Scoi2010]游戏 二分图
    BZOJ3613: [Heoi2014]南园满地堆轻絮
    BZOJ4590: [Shoi2015]自动刷题机
    [JSOI2008]星球大战starwar BZOJ1015
    Rmq Problem/mex BZOJ3339 BZOJ3585
  • 原文地址:https://www.cnblogs.com/riordon/p/3041034.html
Copyright © 2011-2022 走看看