2.c++面向对象(六)
一.匿名对象
#include<iostream>
using namespace std;class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};class Solution {
public:int Sum_Solution(int n) {//...return n;}
};int main()
{A aa1;A aa2(1);// 匿名对象,生命周期只在当前这一行// 这是即用即销毁的对象A(2);A aa3(1);Solution s1;s1.Sum_Solution(10);Solution().Sum_Solution(10);return 0;
}
二.拷贝对象时的一些编译器优化
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}A(int a1, int a2){cout << "A(int a1, int a2)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a = aa._a;}return *this;}~A(){cout << "~A()" << endl;}
private:int _a;
};//void f1(const A aa)
//没有引用传参的话,传参的时候,还会有一次拷贝构造和析构
int main()
{// 引用传参// aa1的构造,和传参的构造和析构A aa1;f1(aa1);cout << endl;//连续的一个表达式中,构造+拷贝构造 -> 优化为直接构造//一次拷贝和析构f1(A(2));cout << endl;//和上面是一样的f1(2);cout << endl;return 0;
}void f1(const A& aa)
{}int main()
{// 引用传参// 只有aa1的构造A aa1;f1(aa1);cout << endl;// 传匿名对象// 构造之后,传参之后,再次进行析构(一次构造和析构)f1(A(2));cout << endl;//隐式类型转换//(一次构造和析构)f1(2);cout << endl;return 0;
}
我们可以尝试理解这些代码
下图也是编译器做的一些优化:
所以我们可以看到,传引用返回和现在这个程序的效率是一致的
拷贝构造和赋值无法进行优化
A f2()
{A aa;//如果加了这么多的内容cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;cout << "1111111111" << endl;return aa;
}int main()
{// 连续一个表达式中,拷贝构造 + 拷贝构造 - 》优化为一个拷贝构造A ret1 = f2();cout << endl;// 无法优化,建议尽量不要这样写A ret2;ret2 = f2();cout << endl;return 0;
}
release下面可能优化会开的更大,如果定义aa,并且直接返回的话,编译器发现我们好像没干啥事情,就直接跨行进行优化了(了解)
三.再次理解类和对象
四.题目
https://www.nowcoder.com/practice/769d45d455fe40b385ba32f97e7bcded?tpId=37&&tqId=21296&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
可以尝试写一下这个题目:
题目解析:
五.日期类纠正:
六.构造和析构的顺序
void f2()
{// 局部的静态第一个调用时构造初始化static A aa3;
}// 全局对象,再main函数之前构造
A aa0;int main()
{// 后定义先析构A aa1;A aa2;f2();cout << "1111111111111111111" << endl;f2();cout << "1111111111111111111" << endl;return 0;
}