---“不要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;
}