Effective C++笔记之二十二:C++临时变量的析构

先来看段代码

#include <iostream>
#include <string>

std::string myBlog()
{
    return "https://blog.csdn.net/caoshangpa";
}

int main()
{
    const char *p = myBlog().c_str();
    std::cout << p << std::endl;

    return 0;
}

预期输出:https://blog.csdn.net/caoshangpa,但实际上无论是VC++还是g++编译器下,输出都是乱码。
但是把字符串改短点,比如改成“CSDN”,VC++编译器下输出为空,但在g++编译器下,是能正常输出的。
因此这个问题非常隐蔽,不仅与编译器相关,还和临时变量的具体内容相关,一旦发生,很难定位。
myBlog()是一个零时变量,等价于std::string("https://blog.csdn.net/caoshangpa")。这行语句结束时这个变量就被析构了,指针c_str()指向的内存也被回收,所以下面使用的c_str()指向的内存已经被释放了,所以无法输出我的博客网址。
改成下面这样能正常输出:

#include <iostream>
#include <string>

std::string myBlog()
{
    return "https://blog.csdn.net/caoshangpa";
}

int main()
{
    std::string str = myBlog();
    const char *p = str.c_str();
    std::cout << p << std::endl;

    // 或
    std::cout << myBlog().c_str() << std::endl;

    return 0;
}

那么临时变量是何时析构的呢?再来看段代码

#include <iostream>
#include <string>

class MyClass
{
public:
    MyClass()
    {
        std::cout << "MyClass constructor" << std::endl;
    }

    ~MyClass()
    {
        std::cout << "MyClass destructor" << std::endl;
    }
};

int main()
{
    MyClass(); // 临时对象

    std::cout << "https://blog.csdn.net/caoshangpa" << std::endl;

    return 0;
}

输出结果如下:

并非是:
MyClass constructor
https://blog.csdn.net/caoshangpa
MyClass destructor
这说明在执行完MyClass(); 后,临时对象就析构了。
稍作修改:

#include <iostream>
#include <string>

class MyClass
{
public:
    MyClass()
    {
        std::cout << "MyClass constructor" << std::endl;
    }

    ~MyClass()
    {
        std::cout << "MyClass destructor" << std::endl;
    }
};

int main()
{
    MyClass(),// 如果这里是逗号

    std::cout << "https://blog.csdn.net/caoshangpa" << std::endl;
    std::cout << "CSDN Cao Shang Pa" << std::endl;

    return 0;
}

输出结果如下:

由此可见, 临时对象是在遇到其后的第一个分号(语句结束处)析构的。
在Qt中经常会存在QString转char *的情况

QString str("Hello World!");
const char * arr = str.toStdString().c_str();
char * arr = str.toStdString().data();
const char * arr = str.toUtf8().constData();
char * arr = str.toUtf8().data();
............

根据上面的分析,这些都是存在问题的
参考链接:https://blog.csdn.net/stpeace/article/details/46461167

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

草上爬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值