所以我有一个upDate对象,它有一个指针成员变量,只指向一个默认为1959年5月11日的数组:
upDate::upDate()
{ dptr = new int[3];
dptr[0] = 5;
dptr[1] = 11;
dptr[2] = 1959;
}
现在在我的主要内容我应该覆盖+运算符。
upDate D1(5,9,1994);
upDate D2 = D1+1;//supposed to add 1 more day to the upDate.
但是当我输出D2时,它并没有我5/10/1994。它给了我一个非常大的负数:-572662307 / -572662307 / -572662307.。
这是我的算子+方法:
upDate upDate::operator+(int integer){
upDate temp;
int m = dptr[0];
//cout << m << endl;
int d = dptr[1];
int y = dptr[2];
int julian = convertToJulian(y, m, d);
julian += integer;
//cout << julian << endl;
temp.convertToGregorian(julian);
//cout << temp.getMonth() << " " << temp.getDay() << " " << temp.getYear() << endl;
return temp;
}
该方法中的所有cout都只是我测试它是否正确,它们是正确的。所以,我不认为其中任何一个是不正确的。但是,当我返回临时状态时,我认为在将温度恢复为D2的过程中会丢失一些东西。也许它是一个指针问题?我不太确定。
编辑:这是我的运营商=:
upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
copy.dptr[i] = dptr[i];
return copy;
}
和我的析构函数:
upDate::~upDate()
{
delete []dptr;
}
我想我从来没有制作过复制构造函数......但我对如何制作它很困惑?
答案 0 :(得分:1)
也许这是一个指针问题?
可能。在您的更新中,您说“我想我从未创建过复制构造函数”,这意味着该类会破坏Rule of Three并具有无效的复制语义。当它被复制时(就像从你发布的函数返回时那样),两个副本都包含一个指向同一个数组的指针;据推测,两者都有一个析构函数,删除数组,让另一个对象的指针悬空。
我想我从未做过复制构造函数......但我对如何制作它感到困惑?
制作它的最佳方法不是。停止使用new
并手动处理指针,并从正确的可复制对象构建类;在这种情况下,将dptr
替换为数组或三个命名变量。 (如果你需要一个动态大小的数组,你不在这里,那么std::vector
将是理想的。)
我可能会通过仅存储Julian日来进一步简化它,并且只在必要时转换为Gregorian以进行人类可读的演示。
如果你真的觉得需要通过steam管理内存,那么你需要一个析构函数
~upDate() {delete [] dptr;}
复制构造函数
upDate(upDate const & other) : dptr(new int[3]) {
std::copy(other.dptr, other.dptr+3, dptr);
}
和复制赋值运算符。它应该修改它所调用的对象,而不是它的参数(当然也不是你的参数的本地副本),并且通常应该返回对指定对象的引用,而不是它的副本。
upDate & operator=(upDate const & other) {
std::copy(other.dptr, other.dptr+3, dptr);
return *this;
}
在C ++ 11中,为了提高效率,您可能还需要考虑移动语义。
upDate(upDate && other) : dptr(other.dptr) {
other.dptr = nullptr;
}
upDate & operator=(upDate && other) {
if (this != &other) { // Careful: self-assignment can be tricky
dptr = other.dptr;
other.dptr = nullptr;
}
}
免责声明:此代码是在没有编译器和测试框架的帮助下编写的,因此可能包含错误。不经测试就不要使用它。
tl; dr 内存管理很难。除非你真的需要,否则不要这样做。你不需要在这里。
答案 1 :(得分:0)
您的operator=
功能可以倒退。
//This version tries to make a=b work as though it were b=a
upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
copy.dptr[i] = dptr[i];
return copy;
}
也就是说,通过examples I have seen判断operator=
应该将参数的值复制到当前对象中,然后将其从当前对象复制到参数。
//Corrected version (judging by linked article.)
upDate & upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
dptr[i] = copy.dptr[i];
return *this;
}
答案 2 :(得分:0)
我想我从来没有制作过复制构造函数
否即可。注意这一行upDate D2 = D1+1;
,它会调用复制构造函数而不是operator =,因为你没有指定一个,它会调用编译器生成的复制构造函数来执行成员复制,所以数据成员{{ 1}},他们共享相同的地址。销毁D2.dptr = temp.dptr
后,temp
指向无效的地址,因此它会为您提供垃圾值。