zoukankan      html  css  js  c++  java
  • C++暂时对象

    C++真正所谓的暂时对象是不可见的——不会在你的源码中出现。仅仅要你产生一个non-heap object而没有为它命名,便诞生了一个暂时对象。此等匿名对象通常发生于两种情况:

    一是当隐式类型转换(implicit type conversions)被施行起来以求函数调用可以成功。

    二是当函数返回对象的时候;

    其实另一种情况就是当你建立一个non-heap object对象,也就是无名对象的时候。

    这里举一个常见的easy忽视的错误:

    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv[]) {
        string s1("a"),s2("b");
        const char * s = (s1+s2).c_str();
        printf("%s
    ",s);
    }
    

    这个程序执行的时候你可能会得到正确的结果,但其实这里的做法是不安全的,s1+s2产生的暂时对象会在表达式的结尾被析构。所以假设跟踪堆栈会发如今print语句中s的内存空间已经指向未知地址了。

    这里针对3种会产生暂时对象的情况举例进行说明:

    1.隐式类型转换

    void uppercasify(string& str);
    
    // changes all chars in str to upper case
    char subtleBookPlug[] = "Effective C++";
    uppercasify(subtleBookPlug); //error!!!
    

    由于要使函数调用成功,必须将subtleBookPlug转换成string类型,而编译器觉得你要改变的subtleBookPlug。而类型转换后将产生一个类型为string的暂时对象,而在void uppercasify(string& str)中。被改变的将是这个暂时对象,而不是subtleBookPlug,这显然不是程序猿所期望的。所以C++明智地禁止了这样的行为

    2.函数返回对象

    #include <iostream>
    
    using namespace std;
    
    int func() {
        int itgr;
        return itgr;
    }
    
    int main(int argc, char *argv[]) {
        int in;
        in = func();
    }
    

    函数中的返回值会以值拷贝的形式复制到被调用函数栈中的一个暂时对象。这里表达式func()创建了一个暂时对象。用来存储func()函数返回的对象,暂时对象由func()返回的itgr对象拷贝构造。暂时对象赋值给in后,赋值表达式结束,暂时对象被析构。所以这里就有一个问题。

    int& intref = func();
    

    假设用一个暂时对象去初始化intref引用,一旦该表达式执行结束,暂时对象的生命周期也就结束了。引用的实体已经不复存在。

    3.no heap的对象

    int& intref = int(5);
    int itgr = int(5);
    Calculate(int(5));
    

    上述表达式中的暂时对象用来完毕初始化引用。拷贝构造和实參等作用。

    关于暂时对象生命周期的延长等问题,后面的博客再更新吧。越来越觉得C++真心麻烦…

    haha

  • 相关阅读:
    sql 随机获取100条数据
    NPOI导出信息
    JavaScript打印页面
    生僻字在页面上不显示(䶮)
    C# 下载文件并使用指定名称展示
    layui 表格列编辑获取编辑前的值然后重新赋值,并通过键盘控制编辑位置
    C# 网络图片转base64
    C# WebApi debug模式下编译没有问题,切换到release模式下编译就有异常,但是依旧能生成成功,再切回到debug模式也会报错,也可以生成成功
    HTTP/2
    Class的继承
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5223094.html
Copyright © 2011-2022 走看看