【发布时间】:2020-06-22 23:59:13
【问题描述】:
我在学习 C++ 考试 我被问到在这段代码中,类的 d'tor 是否应该使用 delete[] 而不是 delete:
template <class T>
class ClonePtr
{
private:
T* ptr;
public:
explicit ClonePtr(T* p = nullptr) : ptr(p) {}
~ClonePtr() { if(ptr!=nullptr) delete []ptr; }
ClonePtr(const ClonePtr& other) : ptr(nullptr)
{
*this = other;
}
ClonePtr(ClonePtr&& other) : ptr(other.ptr)
{
other.ptr = nullptr;
}
ClonePtr& operator=(const ClonePtr& other)
{
if (this != &other)
{
delete ptr;
if (other.ptr != nullptr)
ptr = other.ptr->clone();
}
return *this;
}
T& operator*() const { return *ptr; }
};
这个问题的正确答案是肯定的, 但这是为什么呢?
+关于这段代码我还有两个小问题:
- 考试中说T型必须是类,不能是原始类型。 这是为什么呢?
- 另一方面,我尝试编写以下代码:
并得到一个编译器错误:C2664“无法将参数 1 从 A* 转换为 T*”
非常感谢您的帮助。
谢谢:)
【问题讨论】:
-
这是一个糟糕的课程。它不分配任何内存,为什么会删除内存,更不用说
delete[]。 -
没有分配数组的指示。因此使用
delete而不是delete []。delete[]用于删除数组。 -
delete ptr中的operator=是故意的吗?如果是这种情况,并且问题是关于析构函数的,我会说它应该是delete(与另一个匹配)。 -
这实际上是一个很好的例子,说明为什么你应该拒绝
new和delete,无论它们是否是[]版本,并坚持使用容器和智能指针。除非您确切知道某物是如何分配的,因为您分配了它,或者提供商的文档告诉您如何处置它,否则您不应该尝试释放它。它可能是malloced 或自动分配给所有你知道的。 -
ClonePtr<int>将专注于int。这意味着ClonePtr(T* p = nullptr)将变为ClonePtr(int* p = nullptr)。并且想要一个指向int的指针,而不是指向A的指针。ClonePtr<A>将接受指向A的指针。