函数返回值4字节是通过寄存器带回来的,大于4字节小于8字节通过两个寄存器带回来,大于8字节通过临时对象带回来
/*
* 写出高效c++代码,函数返回值的优化
*/
#if 1
#include <iostream>
using namespace std;
class Test
{
};
Test GetObject(Test t)
{
int value = t.GetValue();
Test temp(value);
return temp;
}
int main()
{
Test t1(10);
Test t2;
t2 = GetObject(t1);
}
#endif
/***********运行结果*************/
/*
test()
test()
test(const test &src)
test()
test(const test &src)
~Test()
~Test()
operator=(const test &src))
~Test()
~Test()
~Test()
请按任意键继续. .
*/
/*****************运行结果************************/
/*构造 t1, 构造t2, 调用GetObject函数之前在main函数战争生成临时变量的内存,
隐式的将临时变量的地址传递给GetObject函数,用t1拷贝构造形参t,
调用构造函数生成temp对象,返回temp对象,用temp对象拷贝构造调用GetObject函数之前生成临时变量,
析构temp,析构t,调用赋值重载函数给t2赋值,析构临时量,析构t2,析构t1;
*/
#if 1
#include "Test.h"
Test GetObject(Test& t)
{
int value = t.GetValue();
return Test(value);
}
int main()
{
Test t1(10);
Test t2 = GetObject(t1);
}
#endif
/***********运行结果*************/
/*
test()
test()
~Test()
~Test()
请按任意键继续. . .
*/
/*****************运行结果************************/
/*构造 t1
调用GetObject函数,该函数返回一个临时对象,用构造临时对象构造函数构造对象t2 ps:此时临时对象不生成被编译器优化,直接用构造临时对象的方法构造t2对象, 析构t2,析构t1;
*/
所以,当函数返回一个对象时候应该直接返回临时对象,当接受一个返回对象的函数的返回值时应该定义的时候直接得到返回值(初始化的过程而不是赋值的过程)
/*分配内存、构造成员对象、根据对象的定义方式调用相应的构造函数
*/
构造函数的初始化列表的初始化顺序是由成员变量的定义顺须来决定的,如果一个变量没有初始化则就是无效值.
在参数列表中是初始化,在类体内则是赋值,成员对象的初始化效率要比赋值的效率高(用临时对象拷贝构造新对象,编译器会优化,不生成临时对象,用构造临时对象的方法直接构造新对象)
®
当成员变量是引用的时候,可以调用拷贝构造函数,但不可以拷贝赋值重载函数
当成员变量是常成员变量的时候,可以调用拷贝构造函数,但不可以拷贝赋值重载函数
以上的成员变量都是普通成员变量,static成员变量不会受影响
当返回一个指针或引用的时候和上边就不一样了,需要加上const,常引用
自定义类型引用寄存器带回来的数字,自定义类型不用加const常引用,编译器对待自定义类型和内置类型方式不同
同时用指针指向函数返回值的地址也是ok的, 编译器会生成一个临时对象。编译器对自定义类型的处理和对类对象的处理方式不一样。
坚持✊