[英]Returning an object with a pointer member variable in C++
因此,我有一个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。
这是我的operator +方法:
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;
}
该方法中的所有提示都由我测试,以查看是否正确,而且是正确的。 因此,我认为这些都不正确。 但是,当我返回温度时,我认为在将温度返回为D2的过程中会丢失一些东西。 也许这是一个指针问题? 我不太确定
编辑:这是我的运算子=:
upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
copy.dptr[i] = dptr[i];
return copy;
}
和我的析构函数:
upDate::~upDate()
{
delete []dptr;
}
我想我从来没有做过复制构造函数...但是我对如何制作它感到困惑?
也许这是一个指针问题?
大概。 在您的更新中,您说“我想我从来没有做过复制构造函数”,这意味着该类违反了三则规则并且具有无效的复制语义。 复制后(就像从您发布的函数中返回时一样),两个副本都包含指向同一数组的指针。 大概两个对象都有一个析构函数,该析构函数删除了数组,而另一个对象的指针则悬空了。
我想我从来没有做过复制构造函数...但是我对如何制作它感到困惑?
最好的方法不是。 停止使用new
和手动处理的指针,并从可正确复制的对象构建类; 在这种情况下,请将dptr
替换为数组或三个命名变量。 (如果您需要一个动态大小的数组,而您不在这里,那么std::vector
将是理想的)。
我可能会通过仅存储儒略日来进一步简化它,并且仅在必要时转换为公历,以便于人类可读的演示。
如果您确实需要通过蒸汽管理内存,则需要一个析构函数
~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内存管理很困难。 除非确实需要,否则不要这样做。 您不需要在这里。
您的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;
}
也就是说,从我看到的示例来看 , 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;
}
我想我从来没有做过复制构造函数
不行 注意这条线upDate D2 = D1+1;
,它将调用复制构造函数而不是operator =,因为您没有指定一个,它将调用编译器生成的复制构造函数,该复制构造函数执行成员级复制,因此数据成员D2.dptr = temp.dptr
共享相同的地址。 temp
被销毁后, D2.dptr
指向无效地址,因此它为您提供了垃圾值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.