在下面的代码中实现了一个执行正常的智能指针,但最后我得到以下消息:
以下是代码:
smart_ptr.h
:
#ifndef SMART_PTR_H
#define SMART_PTR_H
/*
Class: Auto_ptr
It implements a generic
smart pointer that doesn't need
to be deleted explicitly, i.e.
it provides garbage collection.
*/
template<class T>
class Auto_ptr{
public:
// constructors
explicit Auto_ptr(T* p = nullptr): value(p) { }; // constructor
Auto_ptr(Auto_ptr& p); // copy constructor
Auto_ptr& operator= (const Auto_ptr& p); // copy assignment
~Auto_ptr() { std::cout << "pointer deleted\n"; delete value; } // destructor
// access operators
const T& operator* () const { return *value; } // dereference operator
const T* operator->() const { return value; } // indirect class member access (arrow) operator
// non-modifying members
T* get() { return value; } // getter method
void reset(T* v); // reassing new value(default value: nullptr)
T* release(); // transfers the object to another pointer; without destroying it
private:
// data member
T* value;
};
//--------------------------------------------------------------------------------------------------------
// class Auto_ptr member implementations
// Constructors
// copy constructor
template<class T>
Auto_ptr<T>::Auto_ptr(Auto_ptr& p) {
value = p.release();
}
// copy assignment
template<class T>
Auto_ptr<T>& Auto_ptr<T>::operator= (const Auto_ptr& p ) {
if (this == &p) return *this;
if (value) delete value;
value = p.value;
return *this;
}
/*
Function: release()
Use: T ptr = auto_ptr_obj.release();
It transfers the pointer value to the
caller, setting the data member value
to nullptr.
*/
template <class T>
T* Auto_ptr<T>::release() {
T* temp = value;
value = nullptr;
return temp;
}
/*
Function: reset()
Use: auto_ptr_obj.release(new_pointer);
It deletes the object pointer to by
pointer value and assings new_pointer;
*/
template <class T>
void Auto_ptr<T>::reset(T* v) {
delete value;
value = v;
}
#endif
main.cpp
:
#include <iostream>
#include "smart_ptr.h"
#include "assert.h"
//=====================================================================
void test1 () {
std::cout <<"\nTest constructor and get() member.\n";
Auto_ptr<int> p(new int);
*p.get() = 5;
std::cout <<"p points to: "<< *p << "\n";
//assert(*p, 5);
std::cout <<"TEST 1 DONE\n";
}
void test2 () {
std::cout <<"\nTest reset() and release() members.\n";
Auto_ptr<int> p(new int);
*p.get() = 5;
std::cout <<"p points to: "<< *p << "\n";
p.reset(new int(10));
std::cout <<"reset() p points to: "<< *p << "\n";
//assert(*p, 10);
int *temp = p.release();
std::cout <<"caller of release(), temp points to: "<< *temp << "\n";
//assert(*temp, 10);
// nullptr dereferece error
// std::cout <<"p after being release()d points to: "<< *p << "\n";
std::cout <<"TEST 2 DONE\n";
}
void test3 () {
std::cout <<"\nTest copy constructor and copy assignment.\n";
Auto_ptr<int> p1(new int(10));
Auto_ptr<int> p2(p1);
std::cout <<"copy constructed p2 points to: "<< *p2 << "\n";
//assert(*p2, 10);
Auto_ptr<int> p3(new int(20));
p1 = p3;
std::cout <<"copy assigned p1 points to: "<< *p1 << "\n";
//assert(*p1, 20);
std::cout <<"TEST 3 DONE\n";
}
//=====================================================================
int main () {
test1 ();
test2 ();
test3 ();
getchar();
}
有趣的是,Live example中的错误不可重复。
这条消息可能是什么原因?
答案 0 :(得分:2)
这通常是“双重删除”的结果 - 在这种情况下,我怀疑这是你的副本分配。
您指定value = p.value;
,并且两个副本都保持相同的值,并且都尝试删除它。
您基本上需要将指针从一个对象移动到另一个对象,就像复制构造函数一样。您还需要删除const
。