• C++基础——匿名对象介绍、拷贝对象时的一些编译器优化


            

    目录

     创建对象的几种方式:

    匿名对象的创建格式: 

    二.编译器对于拷贝对象做出的优化

    场景一: 

    检测:

    优化:

    检测: 

    场景二:

    检测:

    优化: 

    场景三:

    检测: 

    优化: 

    场景四:

    优化: 

    检测:

    整体优化总结:


            通过C++长时间的学习,我们已经学会了好多通过类定义对象的方法,例如:

    1. class A
    2. {
    3. public:
    4. A(int a = 0)
    5. :_a(a)
    6. {
    7. cout << "A(int a)构造" << endl;
    8. }
    9. A(const A& a1) {
    10. cout << "A(const A& a1)拷贝构造" << endl;
    11. }
    12. ~A()
    13. {
    14. cout << "~A()析构" << endl;
    15. }
    16. void Print() {
    17. cout << _a << endl;
    18. }
    19. private:
    20. int _a;
    21. };
    22. class Solution {
    23. public:
    24. Solution(double s= 3.14)
    25. :_st(s)
    26. {
    27. cout << "Solution(double s)构造" << endl;
    28. }
    29. int Sum_Solution(int n) {
    30. //...
    31. return n;
    32. }
    33. ~Solution()
    34. {
    35. cout << "~Solution()析构" << endl;
    36. }
    37. private:
    38. double _st;
    39. };

     创建对象的几种方式:

    1. int main() {
    2. //创建对象的方式
    3. A a1,a2; //方式1:
    4. A a3(10); //方式2:
    5. A a4(a1); //方式3:
    6. A a5 = 20; //方式4:

            方式1:编译器会调用构造函数去创建对象;

            方式2:在调用构造函数的同时给予实参直接赋值;

            方式3:编译器会调用拷贝构造去创建对象;

            方式4:这与方式3等价,且这会让编译器采用隐式类型转换。 

    A a6();	

           要特别注意上面这种创建对象方式,该种方式有歧义,会让编译器不知道该调用构造,还是拷贝构造,所以即使运行成功了,编译器也不会生成a6对象! 

    今天我再来介绍一种定义对象的方法,这种方法被称为匿名对象

    匿名对象的创建格式: 

    类名();

    例: 

    调用结果: 

            解析:通过调试出的结果来看,类A,类Solution的匿名对象刚调用完构造函数就调用析构函数了 ,而之前我们创建的对象都是最后会调用析构函数,因此我们得出一个结论:匿名对象的生命周期是在当前行,执行A();调用构造函数,这行完了之后,跳转到下一行时,编译器会调用析构函数。而一般对象的生命周期是一个局部周期,局部结束才会被销毁。这就是一般对象和匿名对象最大的差别!

            那么匿名对象到底有什么用呢?

            其实你可以理解它是为懒人专用而研发的,~~哈哈哈

    例:

    一般对象调用函数时:

    1. A a1;
    2. a1.Print();
    3. Solution s1;
    4. int n=s1.Sum_Solution(25);

    而匿名对象调用函数时:

    1. A().Print();
    2. int n=Solution().Sum_Solution(70);

    一般对象调用函数需要先创建对象,其次才能再调用函数,需要两行;而匿名对象调用函数时一行就可以解决的,

    二.编译器对于拷贝对象做出的优化

    1. #include
    2. using namespace std;
    3. class A{
    4. public:
    5. A(int a = 0)
    6. :_a(a)
    7. {
    8. cout << "A(int a)构造" << endl;
    9. }
    10. A(const A& aa)
    11. :_a(aa._a)
    12. {
    13. cout << "A(const A& aa)拷贝构造" << endl;
    14. }
    15. A& operator=(const A& aa){
    16. cout << "A& operator=(const A& aa)重载函数" << endl;
    17. if (this != &aa)
    18. {
    19. _a = aa._a;
    20. }
    21. return *this;
    22. }
    23. ~A(){
    24. cout << "~A()析构" << endl;
    25. }
    26. private:
    27. int _a;
    28. };
    29. void f1(A aa){}
    30. A f2(){
    31. A aa(10);
    32. return aa;
    33. }
    34. A f3()
    35. { //注:F2与F3几乎等价
    36. return A(10); //返回匿名对象
    37. }

    场景一: 

    1. int main() {
    2. A a1; //构造
    3. a1 = 20; //构造+拷贝构造+赋值运算符重载
    4. }

    检测:

             第一句调用构造函数创建对象,第二句则是将通过常量20创建临时类A对象(调用构造函数),然后a1拷贝复制(调用拷贝构造)临时类A对象值,总计调用:构造+拷贝构造+赋值重载函数。

    优化:

    1. //优化场景1:以下这句与上面等价
    2. A a1 = 20;

    检测: 

             优化后只调用了构造函数。


    场景二:

    1. A a2(2022);
    2. f1(a2);
    3. //以上两句共调用:构造+拷贝构造

    检测:

            解析:A a2(2022)是正常的调用构造函数+实参赋值创建对象,因为f1函数形参是类类型参数,这是调用构造函数的情况之一,所以总计调用:构造+拷贝构造 

    优化: 

    1. //优化2:注,以下这句与上面等价
    2. f1(A(2022));

            优化后只调用构造函数。         


    场景三:

    f2();		//构造+拷贝构造

             解析:f2函数内部因为创建对象,所以调用构造函数,且返回值为类类型对象,这也是拷贝构造函数调用的情况之一,所以f2函数总计调用:构造+拷贝构造

    1. A ret;
    2. ret=f2(); //总结:构造+拷贝构造+拷贝构造

    检测: 

            总计调用:构造+构造+拷贝构造+赋值重载函数 

    优化: 

    1. //优化3:下面这句与上面两句等价
    2. A ret = f2();

            优化后总计调用:构造+拷贝构造 


    场景四:

        A ret = f2();	//构造+拷贝构造

             总计调用:构造+拷贝构造 

    优化: 

    1. //优化4:极致优化
    2. A ret2 = f3();

    检测:

             优化后总计调用一次构造函数。

    整体优化总结:

            能一句能搞定的事情不要分开去编写,不要做中间商!中间商不仅赚不了差价,而且还会赔本!!!

  • 相关阅读:
    C++进制转换
    一文搞懂并查集
    Spring异步任务async介绍与案例实战
    Windows安装配置Vagrant
    [数据结构与算法] 线性表之单链表基本操作
    云原生系列之管理docker容器中的数据管理实战
    P5143 攀爬者(快速排序)
    vue全局设置传值到后台不能为null
    【Java 进阶篇】深入了解 JavaScript 的 innerHTML 属性
    程序员从网上抄代码,被老板发现后....
  • 原文地址:https://blog.csdn.net/weixin_69283129/article/details/127823416