Я искал широкий ответ для ответа на этот вопрос, но безрезультатно. Мой плач выглядит следующим образом:
У меня есть 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, но никто из них не справляется с этой точной проблемой.