Отражение в 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 и т. Д., Которые не всегда тривиальны.

Другие вопросы по тегам