Неразрешенный внешний символ для QObject как элемента (макрос Q_DISABLE_COPY)

template <class T>
class FContainer : public QObject
{

public:

    FContainer();

    inline void append(const T &t);
    inline void clear();
    inline void remove(const T &t);

    inline const T& at(int index) const { return m_list[index]; }
    inline const T& first() const { return m_list.first(); }
    inline const T& last() const { return m_list.last(); }

    inline int indexOf(const T &t){ return m_list.indexOf(t); }
    inline int size() { return m_list.size(); }

signals:

    void appended(const T &t);
    void cleared();
    void removed(const T &t);
    void updated();


private:

    QList<T> m_list;
};

class FSystem
{
public:

    inline const FContainer<FMaterial>& materials() const { return m_materials; }
    inline const FContainer<FObject>& objects() const { return m_objects; }

    inline FContainer<FMaterial>& materials() { return m_materials; }
    inline FContainer<FObject>& objects() { return m_objects; }

    static FSystem* Instance() { return m_instance; }

private:
    FSystem();

    FContainer<FMaterial> m_materials;
    FContainer<FObject> m_objects;

    static FSystem *m_instance;
};

У меня есть проблема с использованием классов QObject в качестве члена класса. Компилятор говорит:

FSystem.obj:-1: ошибка: LNK2019: неразрешенный внешний символ "public: __cdecl FContainer::FContainer(void)" (??0?$FContainer@VFMaterial@@@@QEAA@XZ), на который ссылается функция "private: __cdecl FSystem::FSystem(void)" (??0FSystem@@AEAA@XZ)

Конструктор FContainer здесь

template <class T>
FContainer<T>::FContainer()
    : QObject()
{

}

И конструктор FSystem здесь:

FSystem::FSystem() { }

person Cahit Burak Küçüksütcü    schedule 21.02.2014    source источник
comment
Это не может быть ваш реальный код, так как в нем отсутствуют точки с запятой. Можете ли вы создать SSCCE? В любом случае, я не думаю, что это связано с Q_DISABLE_COPY. Больше похоже на то, что компилятор не способен использовать ctor по умолчанию QObject (тот, у которого один параметр с аргументом по умолчанию) в ctor по умолчанию A. Но, не видя всего задействованного кода, трудно сказать наверняка.   -  person Angew is no longer proud of SO    schedule 21.02.2014
comment
Затем я обновляю его.   -  person Cahit Burak Küçüksütcü    schedule 21.02.2014
comment
Я предполагаю, что вы не реализуете шаблоны в заголовочном файле - точнее, FContainer ctor.   -  person Angew is no longer proud of SO    schedule 21.02.2014


Ответы (2)


Почти наверняка проблема в том, что вы определяете FContainer::FContainer(); в исходном файле, а не в заголовке. Поскольку он находится в классе-шаблоне, компилятор должен иметь возможность видеть тело в точке, в которой оно создано, или выполнить явное создание экземпляра.

person Mark B    schedule 21.02.2014
comment
@CahitBurakKüçüksütcü Я не думаю, что это сработало, поскольку вы еще не пробовали использовать сигналы. К сожалению, они не будут работать, так как у вас нет макроса Q_OBJECT в классе, и вы не можете его иметь, так как это шаблонный класс. - person Kuba hasn't forgotten Monica; 21.02.2014
comment
Нет, не получилось, но я разобрался. Спасибо за твою заботу. - person Cahit Burak Küçüksütcü; 22.02.2014

Хорошо иметь шаблонный объект, но, поскольку он не может иметь макрос Q_OBJECT, он также не может иметь свои собственные сигналы. Если вы попробуете свой код, вы увидите, что невозможно подключиться к сигналам объекта.

Вам необходимо отделить QObject, содержащий сигнал, от класса шаблона. Таким образом, ваши сигналы не могут зависеть от аргумента шаблона: вы вынуждены выдавать варианты вместо T. Именно такой подход используется при реализации QFutureWatcher .

class FContainerBase : public QObject {
    Q_OBJECT
public:
    FContainerBase(QObject*parent = 0);
    Q_SIGNAL void appended(const QVariant &);
    Q_SIGNAL void cleared();
    Q_SIGNAL void removed(const QVariant &);
    Q_SIGNAL void updated();
};

template <class T>
class FContainer : public FContainerBase
{
    QList<T> m_list;
public:
    FContainer() { // implementation in the header! }

    inline void append(const T &t);
    inline void clear();
    inline void remove(const T &t);

    inline const T& at(int index) const { return m_list[index]; }
    inline const T& first() const { return m_list.first(); }
    inline const T& last() const { return m_list.last(); }

    inline int indexOf(const T &t){ return m_list.indexOf(t); }
    inline int size() { return m_list.size(); }
};
person Kuba hasn't forgotten Monica    schedule 21.02.2014