1 以传值的方式给函数攒底参数。
这个不用说,值传递。
2 类型转换生成的临时对象/隐式类型转换以保证函数调用成功
举例1:
# include <iostream>using namespace std;class CTempValue
{
public:int val1;int val2;
public:CTempValue(int v1 = 0, int v2 = 0); //构造函数CTempValue(const CTempValue& t) : val1(t.val1), val2(t.val2) //拷贝构造函数{cout << "调用了拷贝构造函数!" << endl;};virtual ~CTempValue() //析构函数{cout << "调用了析构函数!" << endl;};CTempValue& operator=(const CTempValue& tmpv){//不能用初始化列表,只有构造函数才有初始化列表val1 = tmpv.val1;val2 = tmpv.val2;cout << "调用了拷贝赋值运算符!" << endl;return *this;}public://int Add(CTempValue tobj); //普通成员函数int Add(CTempValue& tobj); //普通成员函数
};CTempValue::CTempValue(int v1, int v2) :val1(v1), val2(v2)
{cout << "调用了构造函数!" << endl;cout << "val1 = " << val1 << endl;cout << "val2 = " << val2 << endl;
}//int CTempValue::Add(CTempValue tobj)
//{
// int tmp = tobj.val1 + tobj.val2;
// tobj.val1 = 1000; //这里修改对外界没什么影响
// return tmp;
//}
int CTempValue::Add(CTempValue& tobj)
{int tmp = tobj.val1 + tobj.val2;tobj.val1 = 1000; //这里修改对外界直接产生影响return tmp;
}int main(int argc, char** argv)
{CTempValue sum;sum = 1000;return 0;
}
===================================
(base) ➜ ./b
调用了构造函数!
val1 = 0
val2 = 0
调用了构造函数!
val1 = 1000
val2 = 0
调用了拷贝赋值运算符!
调用了析构函数!
调用了析构函数!
将100赋值给sum,会触发 1000为构造函数的第一个形参赋值,构造一个临时对象,再调用复制赋值运算符,将值赋值给sum。
举例2:
#include <string>using namespace std;int calc(const string& strsource, char ch)
{const char* p = strsource.c_str();int icount = 0;//....具体的统计代码return icount;
}
int main(int argc, char** argv){char mystr[100] = "I love China,oh,yeah!";int result = calc(mystr, 'o'); //看调用的是哪个calc函数return 0;
}
由于calc的形参和mystr的类型不一样,在调用函数的时候,函数calc第一个参数会触发编译器为我们产生一个类型为string的临时对象,临时对象的构造方式就是用mystr作为参数,调用string的构造函数,这样形参就绑定到了这个string临时对象上。当calc返回的时候,这个临时对象会被自动销毁。
注意:string& strsource前必须加const,strsource是一个引用,如果不加const系统会认为,该值有可能会被修改,但是,strsource是一个临时对象,不能被修改,所以c++标准不允许这种倾向。c++只会为const引用产生临时对象,并不会为非const引用创建临时对象。
3 函数返回对象的时候
函数返回对象,内部会通过要返回的值调用拷贝构造函数创建临时对象,再析构原对象。
CTempValue Double(CTempValue& ts)
{CTempValue a(ts.val1 * 2, ts.val2 * 2);return a;
}
int main(int argc, char** argv)
{CTempValue ts1(10, 20);CTempValue ts3 = Double(ts1);cout << "p = "<< &ts3 <<endl;return 0;
}==================
调用了构造函数! p = 0x16dca9460 ==ts1
val1 = 10
val2 = 20
调用了构造函数! p = 0x16dca93e0 == a
val1 = 20
val2 = 40
调用了拷贝构造函数! p = 0x16dca9440 ==临时对象
调用了析构函数! p = 0x16dca93e0 == 析构a
调用了拷贝构造函数! p = 0x16dca9450 == 临时对象到ts3拷贝构造
调用了析构函数! p = 0x16dca9440 == 析构临时对象
p = 0x16dca9450
调用了析构函数! p = 0x16dca9450 == 析构ts3
调用了析构函数! p = 0x16dca9460 == 洗头ts1
如果开启编译优化,ts3会直接接管临时对象。少一个拷贝构造。【double函数返回的临时对象直接使用了ts3的预留空间】。