一、临时对象的概念
// i++,++i
int i = 1;
int &&r1 = i++; // 右值引用 r1和i之间没有什么关系
r1 = 19;
i = 80;
// 另外一些临时对象,是因为我们代码书写问题而产生的,
// 统一称临时变量为临时对象
// new(堆) delete(释放new的对象) 栈(临时对象)
二、产生临时对象的情况和解决:三种情况和解决方案
CTempValue类的结构
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 << "copy construct" << endl;
}
virtual ~CTempValue() // 析构函数
{
cout << "destructor" << endl;
}
// 拷贝复制运算符
CTempValue& operator=(const CTempValue &tmp)
{
val1 = tmp.val1;
val2 = tmp.val2;
cout << "Copy replication operator " << endl;
return *this;
}
public:
int Add(CTempValue tObj); // 普通函数
int Add1(CTempValue &tObj);
};
2.1以传值的方式给函数传递参数
// 拷贝构造函数在tObj这个临时对象发生
int CTempValue::Add(CTempValue tObj)
{
int tmp = tObj.val1 + tObj.val2;
tObj.val1 = 1000; // 对外界的之没有影响
return tmp; // 会调用析构函数
}
// main函数调用
CTempValue tm(10, 20); // 调用了构造函数
int Sum = tm.Add(tm); // 调用了拷贝构造函数
cout << "Sum = " << Sum << endl;
cout << "tm.val1 = " << tm.val1 << endl;

int CTempValue::Add1(CTempValue &tObj)
{
int tmp = tObj.val1 + tObj.val2;
// 会修改val1的值
tObj.val1 = 1000;
return tmp;
}
// main函数调用
// 调用了构造函数
CTempValue tm(10, 20);
int Sum = tm.Add(tm);
cout << "Sum = " << Sum << endl;
cout << "tm.val1 = " << tm.val1 << endl;

2.2类型转换生成的临时对象/隐士类型转换以保证函数调用成功
类型转换生成的临时对象
CTempValue sumx;
// 产生了真正的临时对象
sumx = 1000;

(1)用1000这个数字创建一个类型为CTempValue的临时对象
(2)调用拷贝赋值运算符把这个临时对象里面的成员值赋给了sumx对象
(3)销毁这个临时对象创建的CTempValue对象
// 把定义对象和给对象初值放在一行上
// 用1000构造sumx对象,而且是直接构造
//在sumx对象预留空间里
// 只调用了一次构造函数
CTempValue sumx = 1000;

隐式类型转换以保证函数调用成功
// 统计字符ch在字符串strsource里出现的次数,把次数返回回去
// strsource这个形参绑定到了string这个临时对象
int calcCount(const string &strsource, char ch)
{// 若不加const 则认为会修改strsource这个临时对象
const char *p = strsource.c_str();
int icount = 0;
// ......
return icount;
}
// main函数调用
char mystr[100] = "I love china!oh yeah!";
// char[] --> string 会产生临时对象
int result = calcCount(mystr,'o');
//C++语言只会为const引用(const string &strsource)
//产生临时变量,而不会为非const引用产生临时变量
string mystr1 = "I love china!oh yeah!";
// 这样加const与不加const时一样的,
//因为不需要产生临时对象
result = calcCount(mystr, 'o');
2.3函数返回对象的时候
CTempValue Double(CTempValue &ts) // 形参未消耗,返回值会消耗
{
CTempValue tmp; // 消耗一个构造函数与析构函数
tmp.val1 = ts.val1 * 2;
tmp.val2 = ts.val2 * 2;
return tmp;
}
// main函数调用
CTempValue ts(10, 20); // 拷贝
// 因为返回临时对象导致占用了一个拷贝构造函数和一个析构函数
Double(ts); // 未接收返回的变量--->释放+析构函数

// 形参未消耗,返回值会消耗
CTempValue Double(CTempValue &ts)
{
// 消耗一个构造函数与析构函数
CTempValue tmp;
tmp.val1 = ts.val1 * 2;
tmp.val2 = ts.val2 * 2;
//产生临时对象,占用一个拷贝构造函数与析构函数
return tmp;
}
// main函数调用
CTempValue ts(10, 20); // 拷贝
// 因为返回临时对象导致占用了一个拷贝构造函数和一个析构函数
CTempValue tx = Double(ts); // 返回对象接收

Double()函数引起的消耗:
CTempValue tmp:会消耗一个构造函数与析构函数
return tmp:产生临时对象,占用一个拷贝构造函数与析构函数
CTempValue ts(10, 20);
CTempValue tx = Double(ts);

类外运算符重载
class mynum
{
public:
int num1;
int num2;
public:
mynum(int num11 = 0, int num21 = 0) :
num1(num11), num2(num21) {}
};
mynum operator+(mynum &tmpnum1,
mynum &tmpnum2)
{
return mynum(tmpnum1.num1 + tmpnum2.num1,
tmpnum1.num2 + tmpnum2.num2);
}
// main函数调用
mynum tmp;
tmp.num1 = 10;
tmp.num2 = 100;
mynum tmp2;
tmp2.num1 = 20;
tmp2.num2 = 200;
mynum tmp3 = tmp + tmp2;
好了,今天的C++知识学到这里就结束了,喜欢的朋友可给我点个赞哦!!!
网友评论