繁体   English   中英

在C ++中使用指针成员变量返回对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM