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;

    }

  • 相关阅读:
    在SQL SERVER 2005中还原数据库时出现错误:system.data.sqlclient.sqlerror 媒体集有 2 个媒体簇 但只提供了 1 个。必须提供所有成员。 (microsoft.sqlserver.smo)
    Mysql的Root密码忘记,查看或修改的解决方法
    Win7系统如何设置FTP详细过程
    该设备或资源(127.0.0.1)未设置为接受端口“16823”上的连接。
    window7防火墙无法更改某些设置,错误代码0×80070422
    访问FTP站点下载文件,提示“当前的安全设置不允许从该位置下载文件”的解决方案
    解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法
    按状态选择链接元素
    类选择器与ID选择器的比较
    关于创建Web图像时应记住的五个要素
  • 原文地址:https://www.cnblogs.com/riordon/p/3041034.html
Copyright © 2011-2022 走看看