一个微软在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=
让我们来现在看一个这样的程序:
#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=