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