我已经四处寻找答案,但没有找到。我的抱怨如下:
我有一个名为 ClassA
的类,大致看起来像这样:
class ClassA : public QObject {
Q_OBJECT
public:
ClassA() { mName = "lol"; }
~ClassA();
void ShowName() { std::cout << mName << std::endl; }
std::string mName;
};
当然,由于我使用 moc,所以在我的项目中这个类被拆分为 cpp 和 hpp 两个文件,但这不是问题的关键。请注意,我故意没有使用 Q_DECLARE_METATYPE,因为我现在实际上并不需要它的功能(QVariant 扩展)。我只关心运行时实例化。
问题在于 Q_OBJECT 禁止复制和赋值构造函数。因此,我必须将 qRegisterMetaType 应用于 ClassA* 而不是 ClassA 本身,这似乎一开始是有效的。
现在,我想通过一个字符串在运行时动态创建这个类并运行 ShowName() 方法。我是这样做的:
int main() {
qRegisterMetaType<ClassA*>("ClassA*");
int id = QMetaType::type("ClassA*");
std::cout << "meta id: " << id << std::endl; // Outputs correct generated user id (not 0)
ClassA* myclass = static_cast<ClassA*>(QMetaType::construct(id));
myclass->ShowName(); // Segfaults, oh dear
return 0;
}
现在,我的问题是,我似乎没有一个正确构造的对象。
如果我们把类改成下面这样:
class ClassA : public QObject {
Q_OBJECT
public:
ClassA() { mName = "lol"; }
ClassA(const ClassA& other) { assert(false && "DONT EVER USE THIS"); }
~ClassA();
void ShowName() { std::cout << mName << std::endl; }
std::string mName;
};
那么我们可以相应地更改我们的程序:
int main() {
qRegisterMetaType<ClassA>("ClassA");
int id = QMetaType::type("ClassA");
std::cout << "meta id: " << id << std::endl; // Outputs correct generated user id (not 0)
ClassA* myclass = static_cast<ClassA*>(QMetaType::construct(id));
myclass->ShowName(); // "lol", yay
return 0;
}
显然,我可以使用我的虚构重载复制构造函数,但这并不合适,Qt建议只使用指向QObjects的指针。
有人看出问题在哪里吗?此外,我知道在SO上有类似的问题,但没有一个问题涉及到这个确切的问题。
ClassA* myclass = static_cast<ClassA*>(*(QMetaType::construct(id)));
会有什么区别吗?QMetaType::construct(id)
返回一个指向指针的指针,对吧?所以,为了明确起见,你需要转换内部指针。这会改变什么吗? - Dave Mateer