Отражение в C ++ Qt с копированием и назначением - PullRequest
6 голосов
/ 23 июля 2011

Как указывает документация 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 ]

14 голосов
/ 26 августа 2011

Если вас интересует только отражение для

  • название класса,
  • перечисления и флаги (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.

2 голосов
/ 26 августа 2011

Вы, безусловно, можете реализовать как конструктор копирования, так и оператор назначения копирования в производном классе, но это, вероятно, признак плохого дизайна. Возьмите этот пример:

#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!. Когда базовый класс объявляет свой конструктор копирования / оператор копирования как закрытый, это не мешает производным классам реализовывать свои собственные версии. Он просто не позволяет производным классам вызывать версии базового класса .

И в этом заключается проблема: всегда хорошо проверять, чтобы вы скопировали все части объекта, чтобы у вас действительно было две разные копии. Часть вашего объекта включает в себя данные, принадлежащие базовому классу, поэтому вы всегда должны вызывать конструктор копирования / оператор назначения копирования, чтобы убедиться, что сделана полная копия. Но эти данные не подлежат копированию. Таким образом, невозможно скопировать все части объекта.

Это зависит от вас, если вы хотите придерживаться этого дизайна. Вы должны задать себе одну важную вещь: действительно ли ваш производный класс вообще должен быть копируемым? Если нет, то не о чем беспокоиться!

1 голос
/ 23 июля 2011

Я не знаю много о qt, но если конструктор копирования не разрешен, то должна быть причина для этого (что обсуждается в ссылке, которую вы разместили). Вы можете изменить свой дизайн, чтобы не иметь его.

Тем не менее, если вы настаиваете, то memcpy может быть вашим последним средством. Я не рекомендую это лично, потому что вы должны позаботиться о глубоком копировании, vtable и т. Д., Которые не всегда тривиальны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...