我正在尝试实现一个非常简单的SmartPointer用于学习目的,但是我正在努力解决我似乎无法调试的错误。即使在调试模式下,我也没有明确的错误信息,只有运行时断言。
到目前为止,这是SmartPTR的代码:
template <typename TYPE>
class SmartPointer
{
TYPE* pData;
public:
SmartPointer(void)
: pData(0)
{
std::cout << "DEFAULT CTOR" << std::endl;
}
SmartPointer(TYPE* data)
: pData(data)
{
std::cout << "CTOR WITH TYPE*" << std::endl;
}
SmartPointer(const SmartPointer<TYPE>& rhs)
{
std::cout << "COPY CTOR" << std::endl;
}
~SmartPointer(void)
{ delete pData; }
SmartPointer<TYPE>& operator=(const SmartPointer<TYPE>& rhs)
{
pData = rhs.pData;
return *this;
}
TYPE* operator->(void)
{ return pData; }
TYPE& operator*(void)
{ return *pData; }
};
我正在使用的这门课程很有前途。它是一个简单的Person类,可以在互联网上的任何地方找到,包含构造函数,复制构造函数和重载赋值运算符。现在有了简单的案例,我没有问题。
SmartPointer<Person> p(new Person("Henry", 42));
p->Display(std::cout, *p); // Prints: Henry - 42
SmartPointer<Person> q(p); // Causes runtime error.
SmartPointer<Person> q;
q = p; // The same runtime error as with copy constructor.
知道这出错了吗?如果它有帮助,那么Person类:
class Person
{
std::string name;
unsigned age;
public:
Person(const char* name, unsigned age)
: name(name), age(age)
{ std::cout << "PERSON CTOR CALLED!" << std::endl; }
Person(const Person& rhs)
: name(rhs.name), age(rhs.age)
{ std::cout << "PERSON COPY CTOR CALLED!" << std::endl; }
~Person(void)
{ }
public:
Person& operator=(const Person& rhs)
{
std::cout << "PERSON ASSIGNMENT OPERATOR CALLED!" << std::endl;
name = std::string(rhs.name);
age = rhs.age;
return *this;
}
public:
static std::ostream& Display(std::ostream& os, const Person& p);
};
std::ostream& Person::Display(std::ostream& os, const Person& p)
{
return os << p.name << " - " << p.age << std::endl;
}
感谢您的帮助! - 乔。
答案 0 :(得分:2)
您的智能指针只是复制复制构造函数和赋值运算符中的基础指针。它还删除析构函数中的指针。因此,每次复制或分配其中一个智能指针时,您都会获得多个对象,这些对象持有指向他们都将尝试删除的内容的指针。
关于复制构造函数(感谢@andyprowl指出这一点),智能指针类包含一个未初始化的指针,它试图在析构函数中调用delete
。这是未定义的行为。
此问题没有通用解决方案:您必须指定智能指针的行为方式,以及它实现的所有权类型(如果有)。