C++ 当作为QString返回时,在temp上使用c_str是否仍然会失败?
我知道当错误地使用c_str时会出现指针悬空的情况。像这样:C++ 当作为QString返回时,在temp上使用c_str是否仍然会失败?,c++,qt,c++11,memory,qt5,C++,Qt,C++11,Memory,Qt5,我知道当错误地使用c_str时会出现指针悬空的情况。像这样: const char* str_ptr = functionReturningString().c_str(); // str_ptr is invalid, as the returned string from the function was temporary, and c_str simply points to that array. 我想知道这是否仍然适用于此代码(C++11,Qt5.5) 这是使用to_string函
const char* str_ptr = functionReturningString().c_str();
// str_ptr is invalid, as the returned string from the function was temporary, and c_str simply points to that array.
我想知道这是否仍然适用于此代码(C++11,Qt5.5)
这是使用to_string
函数的uuid类
它返回一个std::string
。这是一个临时对象,我认为c_str()
很危险
返回类型QString
是否以某种方式改变了这一点?我不确定这是否意味着:
返回QString(to_string(_uuid).c_str())代码>(我只是猜测)
如果我没有弄错的话,它应该创建一个副本(如果你看构造函数的话)
问题:安全吗?或者在构建QString
之前,temp是否已销毁?来回答问题
安全吗?或者在构建QString
之前,温度是否已销毁
它是安全的
正如前面提到的OP一样,std::string::c_str()
的结果只有在相应的std::string
保持不变(包括未删除)时才有效
函数必须返回QString
,并且返回
用const char*
调用。
如果编译器发现从const char*
到QString
的转换,则编译器将接受它。
在某些条件下,它将:
构造一个用8位字符串str初始化的字符串。使用fromUtf8()函数将给定的常量字符指针转换为Unicode
编译应用程序时,可以通过从ASCII定义QT_NO_CAST_来禁用此构造函数。例如,如果希望确保所有用户可见的字符串都经过QObject::tr(),这将非常有用
因此,问题归结为:
从返回到_string()
的std::string
是否足够长,可以向QString
的构造函数提供指向其内部原始字符串的指针
是的
发件人:
所有临时对象都将被销毁,这是计算(词汇上)包含创建它们的点的完整表达式的最后一步,如果创建了多个临时对象,它们将按照与创建顺序相反的顺序销毁。即使评估以抛出异常结束,这也是正确的
在本例中,完整表达式为to_string(_uuid).c_str()
(即返回之后和之前的所有内容)
为了使其更加明确和健壮(例如,独立于是否定义了ASCII的QT\u NO\u CAST\u),我将其写成:
QString UUId::toString() const
{
return QString::fromUtf8(to_string(_uuid).c_str());
}
但是
应该相当等效,因为这将假定传递的参数的UTF-8编码内容也是如此。()来回答这个问题
安全吗?或者在构建QString
之前,温度是否已销毁
它是安全的
正如前面提到的OP一样,std::string::c_str()
的结果只有在相应的std::string
保持不变(包括未删除)时才有效
函数必须返回QString
,并且返回
用const char*
调用。
如果编译器发现从const char*
到QString
的转换,则编译器将接受它。
在某些条件下,它将:
构造一个用8位字符串str初始化的字符串。使用fromUtf8()函数将给定的常量字符指针转换为Unicode
编译应用程序时,可以通过从ASCII定义QT_NO_CAST_来禁用此构造函数。例如,如果希望确保所有用户可见的字符串都经过QObject::tr(),这将非常有用
因此,问题归结为:
从返回到_string()
的std::string
是否足够长,可以向QString
的构造函数提供指向其内部原始字符串的指针
是的
发件人:
所有临时对象都将被销毁,这是计算(词汇上)包含创建它们的点的完整表达式的最后一步,如果创建了多个临时对象,它们将按照与创建顺序相反的顺序销毁。即使评估以抛出异常结束,这也是正确的
在本例中,完整表达式为to_string(_uuid).c_str()
(即返回之后和之前的所有内容)
为了使其更加明确和健壮(例如,独立于是否定义了ASCII的QT\u NO\u CAST\u),我将其写成:
QString UUId::toString() const
{
return QString::fromUtf8(to_string(_uuid).c_str());
}
但是
应该相当等效,因为这将假定传递的参数的UTF-8编码内容也是如此。()代码的最小化版本是:
QString toString(const boost::uuids::uuid &uuid)
{
return to_string(uuid).c_str();
}
这是安全的,因为您正在使用c_str()
来初始化QString
的内容QString
将C字符串视为UTF-8,并通过从UTF-8到UTF-16的转码初始化其内部UTF-16存储。这当然会复制所有数据,因此当返回的完整表达式完成计算时,QString
就被构造出来了。只有这样,您通过c_str()
访问的std::string
才会被销毁
return
在这里所做的工作如下:
QString toString(const boost::uuids::uuid &uuid)
{
return QString(to_string(uuid).c_str());
}
同样:析构函数在对完整表达式求值后运行。完整表达式是QString
构造函数调用。因此,临时std::string
必须处于活动状态,直到QString
完成构造
而这个QString
结构总是一个副本。无论C字符串来自何处,它都会在转码到UTF-16时被复制。换句话说:拷贝不是比特
QString toString(const boost::uuids::uuid &uuid)
{
return to_string(uuid).c_str();
}
QString toString(const boost::uuids::uuid &uuid)
{
return QString(to_string(uuid).c_str());
}