C++ 在void指针之间来回转换QObject是否会丢失数据?
我试图将我的对象投射到空指针上或从空指针上投射 这就是我的类继承的方式:C++ 在void指针之间来回转换QObject是否会丢失数据?,c++,qt,void-pointers,C++,Qt,Void Pointers,我试图将我的对象投射到空指针上或从空指针上投射 这就是我的类继承的方式: #ifndef EVERYTHING_H #define EVERYTHING_H #include <QString> #include <QObject> struct Base { public: const QString name; explicit Base(const QString& n) : name { n } {} };
#ifndef EVERYTHING_H
#define EVERYTHING_H
#include <QString>
#include <QObject>
struct Base
{
public:
const QString name;
explicit Base(const QString& n)
: name { n } {}
};
class A : public QObject, public Base
{
Q_OBJECT
public:
explicit A(QObject *parent = nullptr)
: QObject(parent),
Base("name") {}
};
#endif // EVERYTHING_H
aa
与原始指针的地址不同,并且可以工作,而第二个aa
突然指向原始地址,但不工作注意:如果一个不是QObject(只是Base),一切都正常,每次我都会得到“name”。我需要先从A到Base,然后从Base到void,然后再从void到Base。浇铸的顺序显然需要颠倒。我需要先从A浇铸到底部,然后从底部浇铸到空隙,然后再从空隙浇铸到底部。强制转换的顺序显然需要颠倒。在继承层次结构上下强制转换指针时,不能保证指针中的底层内存地址保持不变。根据涉及的继承细节,可能需要进行调整,以确保生成的指针最终指向对象的适当部分。(例如,这种情况可能发生在多重继承中。) 通常情况下,编译器会为您处理这些细节,但当您涉及
void*
时,编译器将无法知道发生了什么。所以,正确地做事完全取决于你
在这种情况下:
A *a = new A();
auto aa = static_cast<Base*>(a);
编译器获取a
中的内存地址,将其直接复制到v
,然后将其直接复制到aa
。没有进行任何调整。因此,通过颠覆编译器的类型知识,您最终遇到了一个问题
我很确定我听说过,你应该只从void*
返回到最初被铸造到void*
的确切类型。这种情况就是一个例子。因此,如果我们改变它:
A *a = new A();
void* v = static_cast<void*>(a);
A* aa = static_cast<A*>(v);
Base* base = static_cast<Base*>(aa);
A*A=newa();
void*v=静态铸件(a);
A*aa=静态_型铸造(v);
底座*底座=静态铸件(aa);
然后您会发现它是有效的。在继承层次结构上下转换指针时,不能保证指针中的底层内存地址保持不变。根据涉及的继承细节,可能需要进行调整,以确保生成的指针最终指向对象的适当部分。(例如,这种情况可能发生在多重继承中。) 通常情况下,编译器会为您处理这些细节,但当您涉及
void*
时,编译器将无法知道发生了什么。所以,正确地做事完全取决于你
在这种情况下:
A *a = new A();
auto aa = static_cast<Base*>(a);
编译器获取a
中的内存地址,将其直接复制到v
,然后将其直接复制到aa
。没有进行任何调整。因此,通过颠覆编译器的类型知识,您最终遇到了一个问题
我很确定我听说过,你应该只从void*
返回到最初被铸造到void*
的确切类型。这种情况就是一个例子。因此,如果我们改变它:
A *a = new A();
void* v = static_cast<void*>(a);
A* aa = static_cast<A*>(v);
Base* base = static_cast<Base*>(aa);
A*A=newa();
void*v=静态铸件(a);
A*aa=静态_型铸造(v);
底座*底座=静态铸件(aa);
然后你会发现它是有效的。QObject和template类实际上与这个问题相关吗?换句话说,如果
A
只是直接从Base
派生而来,而没有其他东西,你还会有同样的问题吗?@JarMan我想我不会,但我确实会。刚刚测试过。在没有模板的情况下也是一样,我编辑了这个问题。@JarMan刚刚测试过,如果一个不是QObject,问题就会消失。所以它与Qt有关。但是,它必须是QoObject。。。我想这个问题更可能是由于多重继承,而不是QObject造成的。@JarMan我需要先从A到B,然后从B到D,然后再从D到B。喜欢相同的顺序,但相反QObject和template类是否与问题实际相关?换句话说,如果A
只是直接从Base
派生而来,而没有其他东西,你还会有同样的问题吗?@JarMan我想我不会,但我确实会。刚刚测试过。在没有模板的情况下也是一样,我编辑了这个问题。@JarMan刚刚测试过,如果一个不是QObject,问题就会消失。所以它与Qt有关。但是,它必须是QoObject。。。我想这个问题更可能是由于多重继承,而不是QObject造成的。@JarMan我需要先从A到B,然后从B到D,然后再从D到B。喜欢相同的顺序,但相反我已经猜出来了,但你的答案解释了为什么你已经猜出来了,但你的答案解释了为什么
A *a = new A();
void* v = static_cast<void*>(a);
A* aa = static_cast<A*>(v);
Base* base = static_cast<Base*>(aa);