Here мы можем прочитать, что никакая копия и оператор присваивания копии не могут быть оценены. Но here мы можем прочитать, что qRegisterMetaType
и Q_DECLARE_METATYPE
должны иметь открытый конструктор по умолчанию, открытый конструктор копии и публичный деструктор. Вопрос в том, кто говорит ложь? Или я не понял это правильно?Могу ли я создать конструктор для подкласса QObject?
ответ
Все верно:
1. QObject
не может быть скопирован и все его потомки также не могут быть скопированы.
2. Q_DECLARE_METATYPE
принимает объекты с открытым конструктором, конструктором копирования и деструктором.
Нет никаких противоречий, поскольку вы не можете зарегистрировать QObject
потомков с Q_DECLARE_METATYPE
.
EDIT:
При конвертировании класса QVariant
он использует конструктор копирования, чтобы сделать копию объекта:
void *ptr = QMetaType::construct(x->type, copy);
Но почему мой класс должен иметь copy-constructor для работы как QObject? Я имею в виду хранение в QVariant. – VALOD9
Да, чтобы храниться в 'QVariant', ваш класс должен иметь конструктор копирования, но он не работает как QObject, потому что QObject, QWidget ... не может быть сохранен в' QVariant' – Ezee
Добавлено объяснение о конструкторе копирования к ответу. – Ezee
Q_DECLARE_METATYPE
макроса используется для получения информации для пользовательских типов пользователей, если вы хотите использовать их как аргументы SIGNAL/SLOT.
Пример:
struct MyInfo
{
QString name;
QDate birthday;
};
Q_DECLARE_METATYPE(MyInfo)
// ... somewhere in cpp:
{
QObject::connect(obj1, SIGNAL(newData(MyInfo), SLOT(onNewData(MyInfo)));
}
Q_DECLARE_METATYPE
Без макросов вы не могли бы передать MyInfo
как сигнал или слот аргумента.
Если вы используете кросс-резьбовые соединения (Qt::QueuedConnection
, Qt::BlockingQueuedConnection
и т. Д.), Вам также необходимо зарегистрировать свой тип с помощью вызова qRegisterMetatype<MyInfo>();
.
Но это нормально, чтобы использовать Q_DECLARE_METATYPE
зарегистрировать СТРЕЛКИ для QObjects. Например:
class MyItem
: public QObject
{
Q_OBJECT
//...
};
Q_DECLARE_METATYPE(MyItem *)
// or event better Q_DECLARE_METATYPE(QSharedPointer<MyItem>)
Указателей типов POD, которые могут быть построены, скопированные и т.д.
Можно, конечно, реализовать конструктор копирования и оператор присваивания в классе, производный от QObject
, но вы можете» t ссылаются на удаленный конструктор копии базового класса и оператор присваивания. Вам нужно катиться самостоятельно.
Таким образом, вам необходимо жить с тем фактом, что построение или присвоение копии не повлияет на соединения сигнала/слота ни с источником, ни с целевым объектом. Вы также должны решить, как обрабатывается родительское копирование при копировании - любой из трех возможных вариантов полностью произволен, поэтому в большинстве случаев нет смысла копировать объекты, это слишком подвержено ошибкам.
Например, используя copy-and-swap idiom.
class CopyableObject : public QObject
{
Q_OBJECT
public:
friend void swap(CopyableObject & first, CopyableObject & second) {
// d_ptr swap doesn't take care of parentage
QObject * firstParent = first.parent();
QObject * secondParent = second.parent();
first.setParent(0);
second.setParent(0);
first.d_ptr.swap(second.d_ptr);
second.setParent(firstParent);
first.setParent(secondParent);
}
CopyableObject(const CopyableObject & other) : QObject(other.parent()) {
Q_ASSERT(thread() == other.thread());
setObjectName(other.objectName());
blockSignals(other.signalsBlocked());
}
CopyableObject(QObject * parent = 0) : QObject(parent) {}
// C++11 only
#if __cplusplus >= 201103L
CopyableObject(CopyableObject && other) : CopyableObject() {
swap(*this, other);
}
#endif
CopyableObject & operator=(CopyableObject other) {
swap(*this, other);
return *this;
}
};
Обратите внимание, что вам нужно переопределить функцию swap
для производных классов.
- 1. Почему я могу создать конструктор копирования и перегрузить оператор присваивания для подкласса QObject?
- 2. Ошибка с `QObject` подкласса и конструктор копирования:` QObject :: QObject (Const QObject &) является private`
- 3. Могу ли я создать конструктор для Enum?
- 4. Кастинг экземпляра подкласса QObject
- 5. Наследующий конструктор класса QObject
- 6. Могу ли я создать конструктор Java, как конструктор C#?
- 7. Почему я могу назначить QObject * в QObject?
- 8. Могу ли я создать не явный конструктор для класса Java?
- 9. Конструктор подкласса
- 10. Могу ли я подкласса «стандартного» итератора араристов?
- 11. Могу ли я создать экземпляр объекта подкласса от суперкласса
- 12. Пользовательский конструктор подкласса NSManagedObject
- 13. Конструктор подкласса неправильный __init__
- 14. Java-конструктор подкласса
- 15. Преобразование const QObject * в QObject *
- 16. Java конструктор подкласса
- 17. Могу ли я создать конструктор generic без создания класса?
- 18. конструктор копирования для baseclasspointer для подкласса
- 19. Конструктор подкласса с дополнительными атрибутами
- 20. Конструктор подкласса не компилируется
- 21. конструктор подкласса в Java
- 22. Как реализовать конструктор подкласса?
- 23. Конструктор подкласса, не сохраняющий данные для объекта
- 24. Могу ли я использовать дженерики для изменения подписи метода подкласса?
- 25. Могу ли я использовать drawRect для обновления подкласса UIView?
- 26. Могу ли я определить класс определения класса подкласса в Coffeescript?
- 27. Почему я не могу создать свой конструктор для атрибутов?
- 28. QObject: Невозможно создать детей
- 29. Могу ли я использовать QSharedData при наследовании от QObject?
- 30. Подкласс QObject, qRegisterMetaType и конструктор частной копии
Не могли бы вы предоставить любую ситуацию, когда вам необходимо зарегистрировать класс класса QObject в качестве метатипа? Документация в порядке. –
Вам не нужно регистрировать QObject или его подкласс с помощью qRegisterMetaType. – vahancho
'qRegisterMetaType' регистрирует определенные пользователем типы, а не те, которые получены из QObject –