Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从函数返回QString-线程安全? 我是QT新手,但这可能是一个非常基础的C++问题。我有一个返回QString的简单函数: QString testclass::myfunc(int i) { QString result; switch (i) { case 1: result = "one"; break; case 2: result = "two"; break; } return result; }_C++_Qt_Function_Return Value_Qstring - Fatal编程技术网

从函数返回QString-线程安全? 我是QT新手,但这可能是一个非常基础的C++问题。我有一个返回QString的简单函数: QString testclass::myfunc(int i) { QString result; switch (i) { case 1: result = "one"; break; case 2: result = "two"; break; } return result; }

从函数返回QString-线程安全? 我是QT新手,但这可能是一个非常基础的C++问题。我有一个返回QString的简单函数: QString testclass::myfunc(int i) { QString result; switch (i) { case 1: result = "one"; break; case 2: result = "two"; break; } return result; },c++,qt,function,return-value,qstring,C++,Qt,Function,Return Value,Qstring,这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?) QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串) 如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void) 这是实际的函数(清理了一点)-请注意,如果出

这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?)

QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串)

如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void)


这是实际的函数(清理了一点)-请注意,如果出现差异,此函数是静态的:

QString L::toString(const L::editions &level)
{
    QString levelStr;
    switch (level) {
        case L::one:
            levelStr = "one";
            break;
        case L::two:
            levelStr = "two";
            break;
        case L::three:
            levelStr = "thre";
            break;
        default:
            levelStr = "Internal Error";
            break;
    }
    return levelStr;
}
然而valgrind抱怨(第121行是“levelStr=”一“)

1个块中的34个字节肯定会在716的丢失记录197中丢失
在/mnt/lserver2/data/development/haast/src/linfo.cpp:121中的L::toString(L::edition const&;)中
1:malloc in/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
2:QArrayData::allocate(unsigned long、unsigned long、unsigned long、QFlagsQArrayData::AllocationOption)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
3:QString::QString(int,Qt::Initialization)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
4:/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1
5:QString::fromUtf8_helper(char const*,int)在/opt/Qt/5.3/gcc_64/lib/libQt5Core.so.5.3.1中
6:QString::fromUtf8(字符常量*,int)在
7:QString::operator=(char const*)在
8:L::toString(L::Lconst&;)in

QString类提供Unicode字符串

QString存储一个16位QChar字符串,其中每个QChar对应 一个Unicode 4.0字符。(具有上述代码值的Unicode字符) 65535使用代理项对存储,即两个连续的QCHAR。)

Unicode是一种支持大多数书写的国际标准 目前正在使用的系统。它是US-ASCII(ANSI X3.4-1986)的超集 和拉丁语-1(ISO 8859-1),所有US-ASCII/拉丁语-1字符均为 在相同的代码位置可用

在幕后,QString使用隐式共享(写时复制)来 减少内存使用,避免不必要的数据复制。这 还有助于减少存储16位字符的固有开销 而不是8位字符

除了QString之外,Qt还提供了要存储的QByteArray类 原始字节和传统的以8位“\0”结尾的字符串。对大多数人来说 在这里,QString是您想要使用的类。它贯穿始终 QtaPI和Unicode支持确保您的应用程序 如果您想扩展应用程序的 市场在某一点。QByteArray所在的两种主要情况 当您需要存储原始二进制数据时,以及 内存保护非常关键(就像在嵌入式系统中一样)

基本上QString是非常棒的,几乎不用担心。你可以在任何地方使用它,不管你喜欢什么。如果经常追加字符串会导致速度减慢,有一种特殊的方法可以使用字符串生成器,但根据我的经验,在尝试改进QString之前,还有很多地方需要改进

直接回答您的问题:

这安全吗?c编译器是否确保返回值在内存中保留足够长的时间,以便调用函数使用?(或者这有内存损坏的风险)。如果是后者,返回QString的正确方法是什么?(结果变量必须是静态的吗?结果必须是testclass的成员变量吗?)

在上述所有情况下,它都是安全的。只要任何函数都有QString的句柄,共享指针等都会将其保存在内存中。一旦它完全超出范围,它就会自我清理

QString包含常量有关系吗?(什么id案例3将结果分配给随机字符串)

不,没关系

如果myfunc是我想从不同线程调用的静态方法,该怎么办?我是否必须通过引用传入一个额外的Qstring以确保每个调用方都获得自己的变量(并返回void)

您应该使用跨线程保护来包装它,例如
QMutexLocker

更新:QMutexLocker示例

// In your constructor

m_mutex = new QMutex();


// When accessing a shared element across threads

{
    QMutexLocker locker(m_mutex);
    // Accessing a variable is now threadsafe!
    m_sharedDataString += "!";
}

希望对您有所帮助。

QString
是一个值类,如果您无法从函数返回它,它将是无用的。这与
std::string
没有什么不同。两者都可以按照您演示的方式使用

您提到的“常量字符串”的概念是虚构的。没有这样的事。语句
result=“foo”不会生成某种特殊的字符串。这不是C,您没有返回一个
常量char*
——这是有充分理由的

线程安全方面与字符串没有多大关系。显示的方法体可以是静态方法,因为它不使用任何实例数据。它也是一个纯函数,根本无法访问任何共享状态。从定义上讲,这样的纯函数是线程安全的,因为它们不访问共享状态。您可能希望用一个更接近您的问题的示例来修改您的问题,并实际演示一些线程问题

QString
与其他Qt的隐式共享值类一样,只要只从一个线程访问它的特定实例,它就是线程安全的。实例是否从另一个字符串实例分配或复制并不重要。例如:

QString a = "foo";
{
  QFutureSynchronizer sync;
  sync.addFuture(QtConcurrent::run([&a] { a.append("bar"); }));
  sync.addFuture(QtConcurrent::run([&a] { a.append("baz"); }));
}
// This is not thread safe: a might be concurrently accessed from two
// threads. The behavior is undefined. It might format your hard drive.

QString c = "Homer";
QString d = c;
{
  QFutureSynchronizer sync;
  sync.addFuture(QtConcurrent::run([&c] { c.append("'s"); }));
  sync.addFuture(QtConcurrent::run([&d] { d.append(" and Elmer's"; }));
}
// This is thread safe. One of the threads will safely deep-copy the
// c's contents.
Q_ASSERT(c == "Homer's");
Q_ASSERT(d == "Homer and Elmer's");
这个函数返回对象(不是对象上的指针),所以它是安全的(因为有一个QString的复制构造函数,它会将局部变量
result
的内容复制到调用者的外部变量中),我想是这样的。。。。
QString a = "foo";
{
  QFutureSynchronizer sync;
  sync.addFuture(QtConcurrent::run([&a] { a.append("bar"); }));
  sync.addFuture(QtConcurrent::run([&a] { a.append("baz"); }));
}
// This is not thread safe: a might be concurrently accessed from two
// threads. The behavior is undefined. It might format your hard drive.

QString c = "Homer";
QString d = c;
{
  QFutureSynchronizer sync;
  sync.addFuture(QtConcurrent::run([&c] { c.append("'s"); }));
  sync.addFuture(QtConcurrent::run([&d] { d.append(" and Elmer's"; }));
}
// This is thread safe. One of the threads will safely deep-copy the
// c's contents.
Q_ASSERT(c == "Homer's");
Q_ASSERT(d == "Homer and Elmer's");