一个微软在VC++.net 2005中定义的优化-类里面的指针的处理,该如何处理

一个微软在VC++.net 2005中定义的优化--类里面的指针的处理
让我们来现在看一个这样的程序:

#include  
using   namespace   std;
class   HasPtr
{
public:
int   *ptr;
int   val;
HasPtr(const   int   &p,int   i):ptr(new   int(p)),val(i)   {   }
HasPtr&   operator=(const   HasPtr   &rhs)
{
*ptr   =   *rhs.ptr;
val   =rhs.val;
return   *this;
}
~HasPtr()
{
delete   ptr;
}
};

int   main()
{
int   ival   =   5;
HasPtr   a(ival,5);
HasPtr   b(a);
cout < <*(a.ptr);
return   0;
}

这是本来是一个没有任何问题的程序,并且在指针的回收处理上非常好,用的是值型指针来处理类里面的指针,这是C++Primer中的原例。在VC(以后都是指VC++.net   2005)中编译也可以通过,不过运行却会产生错误,会让人很莫名其妙。原代码没有问题,我在Dev-C++4.9.9.0   中编译运行都没有问题。原因在哪里?那就是微软在VC中对类里面的指针做了优化,它会自动帮你清理指针。当你把析构函数中的delete   ptr;去掉后,程序在VC中方能运行正常。不知道这是一个好事,还是一个坏事,当习惯了都由自己来处理一切问题的C++程序员在VC中编程的时候,会自然的删除微软已经为你删除了的指针,当然这是会导致错误的。而且是个很严重很难发现的错误,因为是运行而不是编译的错误!不知道我分析的对不对   ?


------解决方案--------------------
1. HasPtr b(a)

你没有在HasPtr中定义拷贝构造函数,
编译器给你提供的缺省拷贝构造函数按bit拷贝:
于是b.ptr 和 a.ptr是同一个指针!

2. 程序退出时, 调用两次HasPtr的析构函数, 结果因为1, HasPtr.ptr执行两次
delete, 第二次delete时, HasPtr.ptr已经无效, 所以VC给你报错.

所以这是你程序本身的bug!!!
------解决方案--------------------
*ptr = *rhs.ptr;

你程序问题吧?
------解决方案--------------------
不对, HasPtr b = a; 也是调用copy constructor.

HasPtr b;
b = a; // 这才调用operator=