Отражение в C++ Qt с копированием и назначением
Как QObject
документация и многие другие объясняют, QObject
имеет идентификатор и, следовательно, скрывает свой конструктор копирования и оператор присваивания.
Тем не менее, я не вытекаю из QObject
для его функции динамических свойств или функции сигналов / слотов. Мне нужно только отражение или возможность доступа Foo::staticMetaObject
,
class Foo : public QObject {
Q_OBJECT
Q_ENUMS(Color)
public:
enum Color { Blue, Red, Pink };
private:
Color color;
};
Q_DECLARE_METATYPE(Foo::Color)
Я тогда не могу скопировать Foo
с:
Foo a;
Foo b;
a = b;
Какой лучший способ разрешить копирование и назначение в этом случае? Нужно ли мне писать конструктор копирования и оператор присваивания? Как бы они выглядели? Будет ли работать отражение?
3 ответа
Если вы заинтересованы только в отражении
- название класса,
- перечисления и флаги (Q_ENUMS, Q_FLAGS),
- информация о классе ( Q_CLASSINFO),
ты можешь использовать Q_GADGET
вместоQ_OBJECT
:
class Foo {
Q_GADGET
Q_ENUMS(Color)
public:
enum Color { Blue, Red, Pink };
private:
Color color;
};
который объявит и определит Foo::staticMetaObject
,
Вы, конечно, можете реализовать как конструктор копирования, так и оператор присваивания копии в производном классе, но это, вероятно, признак плохого дизайна. Возьмите этот пример:
#include <iostream>
class Base {
public:
Base() {}
private:
Base(const Base& other) {
std::cout << "Base copy constructor invoked!" << std::endl;
}
};
class Derived : public Base {
public:
Derived() {}
Derived(const Derived& other) {
std::cout << "Derived copy constructor invoked!" << std::endl;
}
};
int main(int argc, char** argv) {
Derived a;
Derived b = a;
return 0;
}
Это скомпилируется просто отлично. Однако, как и ожидалось, при запуске полученной программы все, что печатается, Derived copy constructor invoked!
, Когда базовый класс объявляет свой конструктор копирования / оператор копирования как частный, это не мешает производным классам реализовывать свои собственные версии. Он просто не позволяет производным классам вызывать версии базовых классов.
И в этом заключается проблема: всегда полезно проверять все части объекта, чтобы у вас действительно было две разные копии. Часть вашего объекта включает в себя данные, принадлежащие базовому классу, поэтому вы всегда должны вызывать конструктор копирования / оператор копирования, чтобы убедиться, что сделана полная копия. Но эти данные не подлежат копированию. Таким образом, невозможно скопировать все части объекта.
Это зависит от вас, если вы хотите придерживаться этого дизайна. Один важный вопрос, который нужно задать себе: действительно ли ваш производный класс должен быть копируемым? Если нет, то не о чем беспокоиться!
Я не знаю много о qt
, но если конструктор копирования не разрешен, то должна быть причина для этого (которая обсуждается в ссылке, которую вы разместили). Вы можете изменить свой дизайн, чтобы не иметь его.
Тем не менее, если вы настаиваете тогда memcpy
может быть вашим последним средством Я не рекомендую это лично, потому что вы должны заботиться о глубоком копировании, vtable и т. Д., Которые не всегда тривиальны.