I've been searching far and wide for an answer to this but to no avail. My lament is as follows:
I have a ClassA
that roughly looks like this:
class ClassA : public QObject {
Q_OBJECT
public:
ClassA() { mName = "lol"; }
~ClassA();
void ShowName() { std::cout << mName << std::endl; }
std::string mName;
};
Of course, since I use moc, this class is actually split into cpp and hpp in my project but that part is not the issue here.
Please note that I do not use Q_DECLARE_METATYPE
on purpose because I don't actually need its features (QVariant expansion) right now. I only care about runtime instantiation.
The issue here is that Q_OBJECT
forbids the copy and assignment constructors. Due to that, I have to apply qRegisterMetaType
not to ClassA
itself but to ClassA*
which seems to work fine at first glance.
Now, I want to create this class dynamically at runtime from a string and run the method ShowName()
. I'm doing that like this:
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;
}
Now, there is my issue. I don't seem to actually have a correctly constructed object there.
If we change the class to look like this:
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;
};
then we can change our program accordingly to:
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;
}
Obviously I could just use my fake overwritten copy constructor but it doesn't feel right and Qt suggests against that and instead suggests the use of pointers to QObjects only.
Does anyone see what's wrong here? Also, I am aware there are similar questions on SO but none of them tackle this exact problem.
See Question&Answers more detail:
os