有一个名为" X"像这样:
class X {
private:
int *ptr;
public:
X() {
ptr = new int[2];
ptr[0] = 0;
ptr[1] = 0;
}
X(int a, int b) {
ptr = new int[2];
ptr[0] = a;
ptr[1] = b;
}
X(const X &val) {
delete[] ptr;
ptr = new int[2];
ptr[0] = val.ptr[0];
ptr[1] = val.ptr[1];
}
X get() {
X ret(ptr[0], ptr[1]);
return ret;
}
};
假设存在使用X v(2, 3)
定义的变量X。
如果我们致电v.get()
,那就没关系。
但是,如果我们致电v.get().get()
,那就不行了。它在复制构造函数的delete[] ptr
部分中产生运行时错误,其内容是我试图删除未定义的(0xcccccccc)指针。
处理此问题的一个可能选择是,使用C ++ - STL,如<array>
或<vector>
。但我想用指针实现。
如何使用基于指针的实现处理此运行时错误?
答案 0 :(得分:1)
简单的答案是你不应该在复制构造函数中delete[] ptr
,因为它是未初始化的。您也不需要delete[] ptr
来完成任务。 仅地点delete
或delete[]
应出现在析构函数中。
整理你的课程,而不改变拥有原始指针
class X {
private:
int *ptr;
public:
X() : X(0, 0) { }
X(int a, int b) : ptr(new int[2]) {
ptr[0] = a;
ptr[1] = b;
}
X(const X &val) : X(val.ptr[0], val.ptr[1]) { }
X& operator=(const X &val)
{
ptr[0] = val.ptr[0];
ptr[1] = val.ptr[1];
return *this;
}
X(X&& val) : ptr(val.ptr) {
val.ptr = nullptr;
}
X& operator=(X&& val) {
std::swap(ptr, val.ptr);
return *this;
}
~X() { delete[] ptr; }
X get() {
return *this;
}
};
作为命名点,构造函数只是一个&#34; copy constructor&#34;如果它将类的实例作为它的单个(非默认)参数。 X::X(int, int)
只是一个构造函数。这意味着最多有4个拷贝构造函数(否则在重载决策下它们会模糊不清)
X::X(X &)
X::X(const X &)
X::X(volatile X &)
X::X(const volatile X &)
然而,定义不止一个是一个可怕的想法,除非你参加混淆比赛