• C++学习:临时对象


    临时对象的产生

    直接调用构造函数将产生一个临时对象

    临时对象的声明周期只有一条语句的时间

    临时对象的作用域只在一条语句中

    临时对象是C++中应当警惕的灰色地带

    1. #include
    2. using namespace std;
    3. class Test
    4. {
    5. private:
    6. int mi;
    7. public:
    8. //有参构造函数
    9. Test(int i)
    10. {
    11. mi = i;
    12. }
    13. //无参构造函数
    14. Test()
    15. {
    16. Test(5); //调用有参构造函数
    17. }
    18. void print()
    19. {
    20. cout << "mi = " << mi << endl;
    21. }
    22. };
    23. int main()
    24. {
    25. Test t; //定义一个类对象,使用无参构造函数
    26. t.print();
    27. return 0;
    28. }

    输出结果

    mi = 0

    结果分析:

    上面的代码,可以看出作者的意图是使用无参的构造函数调用有参构造函数,把对象的成员变量mi初始化为5,但是实际结果却是0(不同的编译器结果是不一样的,应该是随机值)。

    代码

    1. Test()
    2. {
    3. Test(5); //调用有参构造函数
    4. }

    在执行Test(5)的时候就得到一个临时对象,因为我们知道,只要构造函数执行完,对象就创建好了,所以执行了Test(5),就有一个对象被创建,这个对象连名字都没有,Test(5)执行完之后这个对象就会被析构,所以上面的构造函数代码等同于,没有调用Test(5).

    1. Test()
    2. {
    3. //Test(5); //调用有参构造函数
    4. }

    是不是很像某人在群里发一个红包,马上自己就抢走了,这个红包的声明周期就在那一瞬间,跟没发红包是一样的。

    要避免出现临时对象,就不要调用构造函数;但是又想偷懒,少些点代码,可以编写一个私有的成员函数,然后构造函数调用私有成员函数就可以了。

    1. #include
    2. using namespace std;
    3. class Test
    4. {
    5. private:
    6. int mi;
    7. //定义一个私有的成员函数
    8. void init(int i)
    9. {
    10. mi =i;
    11. }
    12. public:
    13. //有参构造函数
    14. Test(int i)
    15. {
    16. init(i); //构造函数调用私有成员函数
    17. }
    18. //无参构造函数
    19. Test()
    20. {
    21. init(5); //构造函数调用私有成员函数
    22. }
    23. void print()
    24. {
    25. cout << "mi = " << mi << endl;
    26. }
    27. };
    28. int main()
    29. {
    30. Test t; //定义一个类对象,使用无参构造函数
    31. t.print();
    32. return 0;
    33. }

    输出结果:

    mi = 5

    这样目的就达到了。

    在构造函数中调用构造函数的情况有点特殊,在main函数调用构造函数也会产生临时对象,如下面代码所示

    1. #include
    2. using namespace std;
    3. class Test
    4. {
    5. private:
    6. int mi;
    7. public:
    8. //有参构造函数
    9. Test(int i)
    10. {
    11. mi = i;
    12. cout << "using Test(int i).\n";
    13. }
    14. //无参构造函数
    15. Test()
    16. {
    17. cout << "using Test().\n";
    18. }
    19. //析构函数
    20. ~Test()
    21. {
    22. cout << "using ~Test().\n";
    23. }
    24. void print()
    25. {
    26. cout << "mi = " << mi << endl;
    27. }
    28. };
    29. int main()
    30. {
    31. cout << "main begin.\n";
    32. Test(); //只要调用了构造函数就会创建一个对象,这句执行完就析构了
    33. Test(5);//只要调用了构造函数就会创建一个对象,这句执行完就析构了
    34. cout << "main end.\n";
    35. return 0;
    36. }

    输出结果

    1. main begin.
    2. using Test().
    3. using ~Test().
    4. using Test(int i).
    5. using ~Test().
    6. main end.

    可以看出,在main函数中调用构造函数,执行完构造函数之后马上就调用析构函数。

    C++的临时对象跟C语言的野指针有的一拼,能避免就避免。

  • 相关阅读:
    Kubernetes的service详解
    【JavaEE】线程安全的集合类
    基于QT+MySQL的相机租赁管理系统
    多线程之四(锁策略+CAS+synchronized)
    《web应用技术》第十次作业
    Linux中的进程终止(详解)
    计算机毕业设计ssm飞机售票管理系统63z52系统+程序+源码+lw+远程部署
    python返回多个值与赋值多个值
    Js与Jq实战:第三讲:JavaScript对象编程
    VirtualBox(内有Centos 7 示例安装)
  • 原文地址:https://blog.csdn.net/m0_49968063/article/details/134050761