Qt中const QString转换 char *可能的坑

 更新时间:2023年07月25日 10:54:31   作者:Monster_H7  
本文主要介绍了Qt中const QString转换 char *可能的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、遇到的问题

现在有一个这样的需求,需要将const QString 转换成  char *

例如:  

const QString q_ip = "192.168.1.1";
const char* kc_ip = q_ip.toStdString().c_str(); //单步调试显示的结果可能会是'\0'
char* k_ip = const_cast<char*>(kc_ip);

而当我这样写时:

std::string str_ip = str.toStdString();
const char* kc_ip = str_ip.c_str();
//kc_ip 是"192.168.1.1" ,printf 输出也是正常的,不是空

这是由于:

str.toStdString().c_str()中toStdString()是一个临时std::string变量,而c_str()是指向这个临时std::string变量的字符串地址,所以传给c时这个临时std::string变量已经被析构,其内容是空,c_str()自然就是'\0'。不过这种情况在未知情况下发生,有时直接写QString::toStdString().c_str() 也是好用的。

这个函数返回一个与这个QString内容相同的std::string对象。注意这个函数的返回值是一个对象。

二、查阅其他说明

在 C++ 中,函数返回对象一般是类似下面的代码:

clazz foo() const { clazz c; c.member = 0; return c; }
clazz foo ( ) const
{
     clazz c ;
     c . member = 0 ;
     return c ;
}

注意这里的返回对象,其实是一个临时对象。在上面代码中,虽然我们在函数体内创建了一个clazz的对象c,但返回的并不是“这个”对象,而是由 C++ 创建一个临时对象,再将这个临时对象返回。注意这里是“临时对象”,临时对象是有生命周期的。《C++ 程序设计语言》第 10 章中写道,“除非一个临时对象被约束到某个引用,或者被用于作为命名对象的初始化,否则它将在创建它的那个完整表达式结束时销毁”。所谓“完整表达式”,是指不是其它表达式的子表达式的表达式。简单来说,一个完整表达式的标识一般是一个分号。

这句看似绕口的话解释了之前所有的现象。在第一段代码中,由于函数返回一个临时变量,我们立即调用了这个临时对象的c_str()函数。这一切都没有问题。之后,完整表达式结束(遇到分号),而这个临时变量没有赋值给某个引用或用于给某个对象初始化,所以这个临时变量被立即销毁。由此对象获得的c_str()函数结果同样被销毁,因此发生段错误。在第二段代码中,这个临时变量用于给sstr对象初始化,我们之后调用的是这个新的被初始化完成的对象的函数,也就是正常的。第三段代码虽然也没有赋值给某个引用或用于给某个对象初始化,但在str.toStdString().c_str()语句结束后,表达式并没有结束,而是继续执行函数调用。直到函数调用返回,才遇到代表表达式结束的分号,此时临时变量才会销毁。而这时候我们已经成功执行了函数代码。所以一切都没有问题。

这种看似奇怪的现象其实只是一个 C++ 语言的陷阱,甚至与 Qt 没有一点关系。同样类似的陷阱还可能发生在QString::toUtf8()、QString::toAscii()之类的函数身上,值得注意!

到此这篇关于Qt中const QString转换 char *可能的坑的文章就介绍到这了,更多相关Qt const QString转换 char *内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言运算符的优先级和结合性实例详解

    C语言运算符的优先级和结合性实例详解

    本文主要介绍C语言运算符的知识,这里对运算符的优先级和结合性做出了详解,并附实例代码,希望能帮助有需要的小伙伴
    2016-07-07
  • C语言入门篇--变量的左值和右值

    C语言入门篇--变量的左值和右值

    本篇文章是基础篇,适合c语言刚入门的朋友,本文对初识c语言的指针和指针变量做了简单的分析,帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • 使用C语言实现最小生成树求解的简单方法

    使用C语言实现最小生成树求解的简单方法

    这篇文章主要介绍了使用C语言实现最小生成树求解的简单方法,包括Prim算法和Kruskal算法的两种求解方式,需要的朋友可以参考下
    2015-08-08
  • C语言实现通用数据结构之通用链表

    C语言实现通用数据结构之通用链表

    这篇文章主要为大家详细介绍了c语言实现通用数据结构之通用链表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 详解C++11中的lambda匿名函数

    详解C++11中的lambda匿名函数

    匿名函数,简单地理解就是没有名称的函数,又常被称为 lambda 函数或者 lambda 表达式,这篇文章主要介绍了C++11中的lambda匿名函数,需要的朋友可以参考下
    2022-11-11
  • C语言修炼之路灵根孕育源流出 初识C言大道生上篇

    C语言修炼之路灵根孕育源流出 初识C言大道生上篇

    C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言
    2022-03-03
  • Qt中TCP协议通信详解

    Qt中TCP协议通信详解

    这篇文章主要为大家详细介绍了Qt中TCP协议通信,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言关于include顺序不同导致编译结果不同的问题

    C语言关于include顺序不同导致编译结果不同的问题

    这篇文章主要介绍了在日常调试C语言中include的顺序不同从而影响最后编译结果不同的问题,究其原因是写代码的习惯所导致,下面跟小编一起来看看吧
    2022-04-04
  • C++面试八股文之智能指针详解

    C++面试八股文之智能指针详解

    智能指针是C++11引入的类模板,用于管理资源,行为类似于指针,但不需要手动申请、释放资源,本文主要为大家介绍了它的相关知识,需要的可以参考一下
    2023-06-06
  • C++模拟实现STL容器vector的示例代码

    C++模拟实现STL容器vector的示例代码

    这篇文章主要为大家详细介绍了C++如何模拟实现STL容器vector的相关资料,文中的示例代码讲解详细,对我们学习C++有一定帮助,需要的可以参考一下
    2022-11-11

最新评论