/////////////////////////////////////////////// 我的注解 int &f(const int&a) { } 那么 f(3)可以. int &f( int&a) { } f(3)错误. 函数调用时形参是实参的拷贝. 同样考虑返回值.不能返回局部变量,而只能返回到一个临时变量中. 临时变量的值可能被丢弃,或者保存到一个生存期更长的变量中. 从汇编讲. 调用时将参数压入栈顶, ======== 将实参拷贝到形参. 返回时 将返回值放到栈顶 ====== 将返回值放到临时变量 返回后,栈指针恢复,但栈顶的临时变量仍在, 此时可将其拷贝到一个生存期更长的变量中. struct o{ int x; int y; }; o f(){ int i=0; int j=1; o o1={30}; int k=2; int l=3; return o1; }; s foo(){ int i=0; int j=1; int k=2; int l=3; printf ( "foo returns\n" ); return o(44,55); }; o o2=f(); // 调用f函数,系统会在运行时栈上开辟一数据结构的内存(活动记录),同时指针指向了该活动记录。 该活动记录中存放有函数返回的地址和返回值、局部变量等数据成员。 return value optimization (RVO) 因为你在return时才会创建这个对象 那么这个对象在这个函数体内就不会再被使用了 编译器可以直接用那个临时变量的空间创建这个对象 不需要再额外多创建一份. Mytime operator *( double i ) const // 生成临时对象 Mytime& operator *( double i ) const // 不生成临时对象
一般对于拷贝构造函数,可以想像,不应该能修改被拷贝的对象.因此要求输入参数是const &, 如果拷贝构造函数的输入参数是一个临时对象呢? 如果被拷贝对象拥有大量资源,那么可见返回的对象也需要拥有相应的资源. 如果被拷贝对象在被拷贝后,就不存在了,那么它就需要随后释放相应的资源. 显然如果能把其拥有的资源直接移动交换给返回的拷贝对象, 而不是一方面对拷贝对象重新分配资源,而被拷贝对象又马上释放资源,能大幅提高效率. 那么拷贝构造函数的输入参数到底能否被修改,与输入参数是否是临时的右值对象有关. 需要两种不同的拷贝构造函数. 那么可以根据输入参数是否是临时的右值对象,进行重载处理. 输入参数是右值引用,表示其是临时的右值对象,可以被修改.. 输入参数是const 左值应用,表示其不能被修改. 编译器根据输入参数的类型,选择合适的函数调用. |
|