Search code examples
c++constructorcopy-constructornrvo

Regarding copy constructor and NRVO


class Date
{
private:
int day,month,year;
public:
Date (int d,int m,int y)
{
day=d;
month=m;
year=y;
}
Date (Date &d)
{ 
day=d.day;
month=d.month;
year=d.year;
}
int monthDays(int month,int year)
{
    if((year%4)==0){
    if(month==4 || month==6 || month==9 || month==11){
        return 30;
    }
    else
    if(month==2){
        return 29;
    }
    else
        return 31;
    }
    else{
        if(month==4 || month==6 || month==9 || month==11){
            return 30;
        }
        else
        if(month==2){
            return 28;
        }
        else
        return 31;
    }
}
Date operator+ (const int k) 
{
    Date copy(day,month,year);
    int inc_days=k;
  if(inc_days<=(monthDays(copy.month,copy.year)-copy.day)){
        copy.day+=inc_days;
        return copy;
    }
    else{
        inc_days-=(monthDays(copy.month,copy.year)-copy.day);
        copy.day=monthDays(copy.month,copy.year);
        while(inc_days>0){
            copy.year+=(copy.month/12);
            copy.month+=1-12*(copy.month/12);
            if(inc_days>monthDays(copy.month,copy.year)){
                copy.day=monthDays(copy.month,copy.year);
                inc_days-=monthDays(copy.month,copy.year);
            }
            else{
                copy.day=inc_days;
                inc_days=0;
            }
        }
        return copy;
    }     
}
};
int main()
{
Date d1(2,3,2004); //uses another constructor //line 1
Date d3(d1); //line 2
Date d2=d1+2; //uses overloaded + operator //line 3
}

Even though line 2 does not take a temporary object as an argument I am still getting a compiler error if I don't add a const in the copy constructor argument. In case of line 3 , the overloaded operator returns an object using NRVO .So it should not use the copy constructor. But it still gives a compiler error. Both these errors vanish if I add a const in the copy constructor argument.But why should it give an error?


Solution

  • Even if the copy constructor is optimized out by the compiler, the code must still compile correctly as if the copy constructor were theoretically called. You need to make the parameter to the copy constructor a const reference in order to take a temporary object.