以下只是记录一下我将工程从EVC+wince5.0 移植到vs2005+wince6.0上的一点解惑。
template <class T> class auto_ptr {
private:
T* m_ptr;
public:
explicit auto_ptr(T* p = 0) : m_ptr(p) {}
auto_ptr(auto_ptr& a) : m_ptr(a.release()) {}
auto_ptr& operator=(auto_ptr& a) {
if (&a != this) {
delete m_ptr;
m_ptr = a.release();
}
return *this;
}
auto_ptr& operator=(T *p) {
if (p != m_ptr) {
delete m_ptr;
m_ptr=p;
}
return *this;
}
~auto_ptr() { delete m_ptr; }
T& operator*() const { return *m_ptr; }
T* operator->() const { return m_ptr; }
operator T*() { return m_ptr; }//add
operator const T*() const { return m_ptr; }//add
T* get() const { return m_ptr; }
T* release() { T* tmp = m_ptr; m_ptr = 0; return tmp; }
void reset(T* p = 0) { delete m_ptr; m_ptr = p; }
};
这是个智能指针类auto_ptr,但这个智能指针所创建的临时指针对象作为一个函数的参数,分别在EVC和vs2005
编译运行产生了不同的行为。
例如:
RFile * fp = new RFile();
m_fp=new CBufFile(auto_ptr<RFile>(fp));
这个CBufFile的构造函数:
CBufFile::CBufFile(auto_ptr<RFile> file) :
m_fp(file),
m_ptr(0)
{
m_cur=&m_b1;
}
1.EVC编译 在wince5.0上运行
auto_ptr<RFile>(fp)是一个临时创建的对象A,
在CBuFile的构造函数里运行auto_ptr的拷贝构造函数,
auto_ptr& operator=(auto_ptr& a) {
if (&a != this) {
delete m_ptr;
m_ptr = a.release();
}
从而将A的指针传递给拷贝者m_fp,A自己release符合使用auto_ptr的原则
(使用auto_ptr的一个重要原则:一个原生指针只能被auto_ptr对象封装一次,不然可能就会产生“野指针”出现violate access)
2. vs2005 +wince 6.0
auto_ptr<RFile>(fp)是一个临时创建的对象.在CBufie的构造函数里也执行一次拷贝构造,但是被拷贝者不是A,而是取出的
A所封装的指针所构造出的对象B,而B的指针确实以拷贝构造的方式将自己的指针传递给了CBufile里的m_fp,但这里缺
违反了上述原则,没有把A release,留下了产生野指针的后患。因为 A与CBufile里的m_fp 封装了相同的指针,其中一个的
生存期完后,就到导致另一个在被使用时产生violate access.
所以使用auto_ptr创建一个智能指针临时对象作为函数参数是一个很危险的事(用上述的auto_ptr)..
总结如下:
1.vs2005--- 智能指针构造的临时对象,不能作为参数使用(使用要小心)
2.打开文件失败,而文件句柄不为空,,说明此时句柄已经被CloseHandle了,不再是有效的句柄.
3.No source Load for dll,,...dll调试中,没有可以执行的代码了,会出现以上的说明。
4.nRefs > 1..出现以上的错误提示,说明了句柄没有关闭,导致内核对象引用计数>1..
5.vs2005 调试中,,执行到某一行代码就不能往下继续执行了,下面行的代码没有被执行,,
说明这一行代码出现了问题(但是调试器可能没有给出提示),一般的原因是非法访问,如访问一个
空指针对象的成员(即指针本身为空,却调用其成员函数,出现voliate access)