简体   繁体   English

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

[英]Returning an object with a pointer member variable in C++

So I have an upDate object that has a pointer member variable that just points to an array that defaults to May 11, 1959: 因此,我有一个upDate对象,该对象的指针成员变量仅指向默认值为1959年5月11日的数组:

upDate::upDate()
{   dptr = new int[3];
    dptr[0] = 5;
    dptr[1] = 11;
    dptr[2] = 1959;
}

Now in my main I'm supposed to override the + operator. 现在在我的主目录中,我应该覆盖+运算符。

upDate D1(5,9,1994);
upDate D2 = D1+1;//supposed to add 1 more day to the upDate.

But when I output D2, it doesn't have me 5/10/1994. 但是当我输出D2时,没有我5/10/1994。 It gives me a really large negative number: -572662307/-572662307/-572662307. 它给了我一个非常大的负数:-572662307 / -572662307 / -572662307。

Here's my operator+ method: 这是我的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;
}

All the couts in that method were just me testing to see if it's correct, and they are. 该方法中的所有提示都由我测试,以查看是否正确,而且是正确的。 So, I don't think any of these are incorrect. 因此,我认为这些都不正确。 However, when I return the temp, I think something gets lost along the way of returning the temp as the D2. 但是,当我返回温度时,我认为在将温度返回为D2的过程中会丢失一些东西。 Maybe it's a pointer issue? 也许这是一个指针问题? I'm not really sure. 我不太确定

Edit: here's my operator=: 编辑:这是我的运算子=:

upDate upDate::operator=(upDate copy) {
for(int i = 0; i<3; i++)
    copy.dptr[i] = dptr[i];
return copy;
}

and my destructor: 和我的析构函数:

upDate::~upDate()
{
    delete []dptr;
}

I guess I never made a copy constructor...But I'm confused on how to make it? 我想我从来没有做过复制构造函数...但是我对如何制作它感到困惑?

Maybe it's a pointer issue? 也许这是一个指针问题?

Probably. 大概。 In your update, you say "I guess I never made a copy constructor", which means that the class breaks the Rule of Three and has invalid copy semantics. 在您的更新中,您说“我想我从来没有做过复制构造函数”,这意味着该类违反了规则并且具有无效的复制语义。 When it's copied (as it is when returning from the function you posted), both copies contain a pointer to the same array; 复制后(就像从您发布的函数中返回时一样),两个副本都包含指向同一数组的指针。 presumably, both have a destructor which deletes the array, leaving the other object's pointer dangling. 大概两个对象都有一个析构函数,该析构函数删除了数组,而另一个对象的指针则悬空了。

I guess I never made a copy constructor...But I'm confused on how to make it? 我想我从来没有做过复制构造函数...但是我对如何制作它感到困惑?

The best way to make it is not to. 最好的方法不是。 Stop using new and manually juggling pointers, and build your class from correctly copyable objects; 停止使用new和手动处理的指针,并从可正确复制的对象构建类; in this case, replace dptr with an array, or three named variables. 在这种情况下,请将dptr替换为数组或三个命名变量。 (If you needed a dynamically-sized array, which you don't here, then std::vector would be ideal). (如果您需要一个动态大小的数组,而您不在这里,那么std::vector将是理想的)。

I would probably simplify it further by only storing the Julian day, and only converting to Gregorian when necessary for human-readable presentation. 我可能会通过仅存储儒略日来进一步简化它,并且仅在必要时转换为公历,以便于人类可读的演示。

If you really feel the need to manage memory by steam, then you'll need a destructor 如果您确实需要通过蒸汽管理内存,则需要一个析构函数

~upDate() {delete [] dptr;}

a copy constructor 复制构造函数

upDate(upDate const & other) : dptr(new int[3]) {
    std::copy(other.dptr, other.dptr+3, dptr);
}

and a copy-assignment operator. 和一个副本分配运算符。 It should modify the object it's called on, not its argument (and certainly not a local copy of its argument, as yours does), and should conventionally return a reference to the assigned object, not a copy of it. 它应该修改被调用的对象,而不是其参数(当然也不能像您一样修改其参数的本地副本),并且通常应返回对已分配对象的引用,而不是其副本。

upDate & operator=(upDate const & other) {
    std::copy(other.dptr, other.dptr+3, dptr);
    return *this;
}

In C++11, you might also want to consider move semantics for the sake of efficiency. 在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;
    }
}

Disclaimer: this code was written without the help of a compiler and test framework, so might contain mistakes. 免责声明:该代码是在没有编译器和测试框架的帮助下编写的,因此可能包含错误。 Don't use it without testing. 未经测试请勿使用。

tl;dr Memory management is hard. tl; dr内存管理很困难。 Don't do it unless you really need to. 除非确实需要,否则不要这样做。 You don't need to here. 您不需要在这里。

Your operator= function works backwards. 您的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;
}

That is, judging by the examples I have seen the operator= should copy the values of the parameter into the current object, where you have it copying from the current object to the parameter. 也就是说,从我看到示例来看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;
}

I guess I never made a copy constructor 我想我从来没有做过复制构造函数

NO . 不行 Note this line upDate D2 = D1+1; 注意这条线upDate D2 = D1+1; , it would call copy constructor instead of operator =, since you don't specify one, it would call the compiler-generated copy constructor which performs a member-wise copy, so the data member D2.dptr = temp.dptr , they share the same address. ,它将调用复制构造函数而不是operator =,因为您没有指定一个,它将调用编译器生成的复制构造函数,该复制构造函数执行成员级复制,因此数据成员D2.dptr = temp.dptr共享相同的地址。 After temp is destroyed, the D2.dptr points to an invalid address, so it gives you garbage value. temp被销毁后, D2.dptr指向无效地址,因此它为您提供了垃圾值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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