临时对象的概念
int i = 1;
int &&r1 = i++; //r1和i之间没有关系
另外一些临时对象,因为我们代码的书写问题而产生。统一称临时变量为临时对象。
产生临时对象的情况与解决
class TmpValue{
public:
int val1;
int val2;
public:
TmpValue(int v1=0, int v2=0);
TmpValue(const TmpValue &tmp);
int Add(TmpValue tpobj);
virtual ~TmpValue();
TmpValue & operator=(const TmpValue &tmp);
};
TmpValue::TmpValue(int v1=0, int v2=0):val1(v1), val2(v2)
{
}
TmpValue::TmpValue(const TmpValue &tmp):val1(tmp.val1), val2(tmp.val2)
{
cout << "调用了拷贝构造函数" << endl;
}
TmpValue::~TmpValue()
{
cout << "调用了析构函数" << endl;
}
int TmpValue::Add(TmpValue tpobj) //tpobj不属于真正的临时对象,真正的临时对象是
//临时生成且在代码中不可见的
{
int Sum = tpobj.val1 + tpobj.val2;
tpobj.val1 = 100;
return Sum;
}
TmpValue & TmpValue::operator=(const TmpValue &tmp)
{
val1 = tmp.val1;
val2 = tmp.val2;
return *this;
}
int main()
{
TmpValue tp(12, 2);
int sum = tp.Add(tp);
cout << tp.val1 << endl;
TmpValue tp2;
tp2 = 100; //这里发生了隐式转换,产生了临时对象,调用了CTempValue的
//TmpValue(int v1, int v2)构造函数
//tp2.val1的值赋值为100
}
类型转换生成临时对象,以保证函数调用成功
步骤:
1、用100这个数字创建了一个类型为TmpValue 的临时对象;
2、调用拷贝赋值运算符把这个临时对象里边的各个成员值赋给了sum 对象
3、销毁这个临时创建的对象TmpValue
隐式类型转换以保证函数调用成功
int clac1(const string &str, char c){
int cont = 0;
//统计代码
return cont;
}
int clac2(string &str, char c){
int cont = 0;
//统计代码
return cont;
}
int main(){
char mystr[100] = "I love china, oh, yeah!";
int result = clac1(mystr, 'o');//C++语言只会为const引用(const string &strsource) 产生临时变量,不会为非const产生临时变量
int result = clac2(mystr, 'o');//C++判断你有修改string临时对象的可能,所以编译不通过
return 0;
}
函数返回对象时
class TmpValue{
public:
int val1;
int val2;
public:
TmpValue(int v1=0, int v2=0);
TmpValue(const TmpValue &tmp);
virtual ~TmpValue();
TmpValue & operator=(const TmpValue &tmp);
};
TmpValue::TmpValue(int v1=0, int v2=0):val1(v1), val2(v2)
{
}
TmpValue::TmpValue(const TmpValue &tmp):val1(tmp.val1), val2(tmp.val2)
{
cout << "调用了拷贝构造函数" << endl;
}
TmpValue::~TmpValue()
{
cout << "调用了析构函数" << endl;
}
TmpValue & TmpValue::operator=(const TmpValue &tmp)
{
val1 = tmp.val1;
val2 = tmp.val2;
return *this;
}
TmpValue Double(const TmpValue &tp)
{
TmpValue tmp;
tmp.val1 = tp.val1 * 2;
tmp.val2 = tp.val2 * 2;
return tmp; //在这里因为tmp为临时对象,它的存在范围就是这个函数体中,出了函数
//体就要被释放,为了让那个为了返回tmp,系统就会调用拷贝构造函数在
//生成一个函数体外的临时对象作为返回值
}
int main()
{
TmpValue tp(12, 2);
Double(tp);
TmpValue tp2 = Double(tp); //return产生的临时对象被tp2接收,没有再调用拷贝构造函数初始化tp2
TmpValue &&tp3 = Double(tp);//return产生的临时对象被tp3右值引用
}
因为返回临时对象,导致占用了一个拷贝构造函数和一个析构函数
Double()函数引起的消耗
TmpValue tmp;会消耗一个构造函数和析构函数
return tmp;会产生临时对象,占用一个拷贝构造函数和析构函数
优化:
TmpValue Double(const TmpValue &tp)
{
return TmpValue(tp.val1 * 2, tp.val2 * 2); //这种方式会直接返回创建的对象,少创
//建了一个临时对象,节省了一个拷贝构
//造函数和析构函数
}
类外的运算符的重载
class myNum
{
int num1;
int num2;
};
myNum operator+(myNum &tmp1, myNum &tmp2)
{
myNum result;
result.num1 = tmp1.num1 + tmp2.num1;
result.num2 = tmp1.num2 + tmp2.num2;
return result;
}
int main(){
myNum n1;
n1.num1 = 10;
n1.num2 = 100;
myNum n2;
n2.num1 = 10;
n2.num2 = 100;
myNum n3 = n1 + n2;
}
1、代码优化
2、需要经验