C++ 将QString转换为uintpttr,Qt/C++;

C++ 将QString转换为uintpttr,Qt/C++;,c++,qt,types,casting,C++,Qt,Types,Casting,在json文件中存储模拟状态时,我希望使用对象地址作为唯一标识符。因此,我将指向对象的指针转换为uintptr\u t Cat myCatptr = new Cat; uintptr_t address= (uintptr_t)myCatptr; 现在我将地址转换为QString: QString str = QString::number(address); 然后,我可以轻松地将QString添加到QJsonObject中。但是如何从QString转换回uintpttr\t呢 在我的机器

在json文件中存储模拟状态时,我希望使用对象地址作为唯一标识符。因此,我将指向对象的指针转换为
uintptr\u t

Cat myCatptr = new Cat;
uintptr_t address= (uintptr_t)myCatptr;
现在我将
地址
转换为QString:

QString str = QString::number(address); 
然后,我可以轻松地将QString添加到QJsonObject中。但是如何从QString转换回uintpttr\t呢

在我的机器上,我知道
sizeof(unsigned long-long)
sizeof(uintpttr\t)
都是8字节。因此我可以使用

address= (uintptr_t)str.toULongLong();
这是否总是正确的,与平台无关?这就需要
sizeof(uintptr\u t)=8字节

再次总结:

  • 我的Ansatz,将其转换为无符号long-long,然后再转换为uintpttru,是否总是有效

  • 如果没有,您知道在任何平台上都可以使用的替代方案吗


  • 标准有保证吗?不。完全可以想象一个平台,
    quolonglong
    是64位的,但是
    uintpttr\t
    是一种神奇的256位扩展类型

    另一方面,a)目前不存在此类平台;b) Qt很可能将
    qulonglong
    定义为该平台上的256位,即使
    unsigned long
    是64位;c) 您没有太多选择:给定一个
    QString
    ,可以轻松将其转换为的最长整数是
    qulonglong

    100%便携式解决方案是使用
    scanf
    SCNxPTR
    (这是将文本转换为
    uintptr\t
    的格式)

        const auto text = str.toStdString();            // Convert to std::string
        sscanf( text.c_str(), "%" SCNxPTR, &address );  // Convert to uintptr_t
        // additional error handling required.
    
    scanf的一般文件。一般形式为:

    sscanf( pointer_to_const_char_array, format, &value1, &value2, ... );
    

    uintptr\u t
    SCNxPTR
    的文档是(我实际上是通过
    SCNxPTR
    找到的)是一个#define宏,它扩展为字符串文本,这是馈送到sscanf(以及scanf家族中的其他人)的正确格式要用十六进制解码
    uintptru\t

    它应该可以正常工作,无论您的目标是哪个当代平台,都有足够的空间来容纳指针。实际上,您可能有点过火了,您可以直接将指针投射到
    qulonglong
    并返回。我已经在x86和arm、32位和64位b上测试了这一点它建立

    您还可以选择指针在特定平台上的大小,并将其移动到字节数组中,然后使用base64编码从该数据创建一个字符串,并在转换回时执行相反的操作。无论该平台上的指针大小如何,都应该备份该指针


    还有另一种更好的方法。你可以实现一个
    QHash
    注册表,不直接使用指针,而是为每一个cat分配一个唯一的整数id,并将其与内存中的地址相关联。这有一个优点,就是在应用程序运行期间保持不变,因此即使在特定对象的ad每次加载时重新创建应用程序数据时,着装都会发生变化。因为您提到“存储状态”我假设您希望以一种在整个应用程序运行期间持续存在的方式来存储它。并且,您可以不做任何保证,而且下次应用程序运行时,几乎不可能在同一地址分配对象,因此任何保存的指针值都将是无用的。因此,可选的解决方案是将指向将持续存在的整数id的实际指针,查找也可能比来回将字符串转换为整数更快。

    我还认为我找到了一个解决方案。如果您发现任何错误,也许您可以对此进行评论

    我的解决方案使用QVariant。我注册数据类型
    uintptr\t
    ,以便通过
    QVariant
    知道它:

    Q\u DECLARE\u元类型(uintptr\u t);
    在Qt核心中定义

    然后

    Strand * myCatptr = strand;
    uintptr_t address= (uintptr_t)myCatptr;
    QString str = QString::number(address);
    
    //string can be passed to QJsonObject
    //...
    //string gets loaded from QJasonObject again to a later point.
    
    //Variant can be converted to uintptr_t, because I registered it
    QVariant var = QVariant::fromValue(str);
    address = var.value<uintptr_t>();
    
    Strand*myCatptr=Strand;
    uintptr_t地址=(uintptr_t)myCatptr;
    QString str=QString::number(地址);
    //字符串可以传递给QJsonObject
    //...
    //字符串再次从QJASOObject加载到稍后的点。
    //变量可以转换为uintptr\t,因为我注册了它
    QVariant var=QVariant::fromValue(str);
    地址=变量值();
    

    它通过QVariant将QString转换为uintpttr\t。

    只要你说“我在我的机器上知道
    sizeof
    ”,那么当不可避免的问题是“这个平台独立吗?”说到这里,答案通常是否定的。它甚至不要求在所有系统上都可用。但很可能在Qt支持的那些系统上。使用对象的地址作为唯一标识符是一种可怕的做法。为什么?我只想简单地可视化,只需一次运行。内存不会通过我的模拟设计重新分配n、 我正在处理图形。你能告诉我为什么这不是一个好的实践吗?你能更详细地解释一下语法吗?我从来没有使用过sscanf。你怎么知道我们必须使用
    SCNxPTR
    ?@newandlost-这有帮助吗?如果你的意思是“我怎么知道寻找SCNxPTR?”-我以前遇到过
    PRI?
    宏(用于printf),因此搜索了“scanf和uintpttr\t”。这实现了什么?从QString到uintptpr\t的转换。