2015-11-18 106 views
0
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 
} 

即使第2行不采取临时对象作为参数,我仍然得到一个编译错误,如果我没有在拷贝构造函数参数添加一个常量。 在第3行的情况下,重载操作符使用NRVO返回一个对象,所以它不应该使用拷贝构造函数。但它仍然给编译器错误。如果我在复制构造函数参数中添加一个常量,这两个错误都会消失。但是为什么它应该给出一个错误?关于拷贝构造函数和NRVO

+0

'Date'是什么?该声明可能涉及此错误。确切的错误也会有帮助。 –

+1

请显示[mcve](http://stackoverflow.com/help/mcve)。 –

+0

日期是我使用3个私有变量日,月和年创建的类。 – CodeMaxx

回答

2

即使拷贝构造函数被编译器优化了,代码仍然必须正确编译,就好像拷贝构造函数在理论上被调用一样。您需要将复制构造函数的参数设置为const引用才能获取临时对象。

+0

为什么理论上的呼叫也应该经历一些具体的原因?在任何特殊情况下都有什么不同? – CodeMaxx

+0

@CodeMaxx这是一个安全机制。如果这个类没有提供一个安全的方法来复制它自己,那么即使编译器能够优化出这些副本,如果它被禁用,它也会按值返回。 –