Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Qt5 qMetaTypeConstructHelper ? (object factory)
Forum Updated to NodeBB v4.3 + New Features

[Solved] Qt5 qMetaTypeConstructHelper ? (object factory)

Scheduled Pinned Locked Moved General and Desktop
7 Posts 2 Posters 4.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sam
    wrote on last edited by
    #1

    Is qMetaTypeConstructHelper deprecated in Qt 5. I am trying to use

    @template <>
    void *qMetaTypeConstructHelper<MyModule>(const MyModule *)
    {
    return new MyModule();
    }

    int MyModule::s_moduleID = qRegisterMetaType<MyModule>("MyModule");
    @

    i get the following errors during compilation :

    MyModule.cpp:17: error: C2143: syntax error : missing ';' before '<'
    MyModule.cpp:17: error: C2988: unrecognizable template declaration/definition
    MyModule.cpp:17: error: C2059: syntax error : '<'

    How to get this working ?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sam
      wrote on last edited by
      #2

      From Qt 5 "qmetatype.h":http://code.woboq.org/qt5/qtbase/src/corelib/kernel/qmetatype.h.html i found that there is a definition like

      @namespace QtMetaTypePrivate {
      template <typename T, bool Accepted = true>
      struct QMetaTypeFunctionHelper {
      static void Delete(void t)
      {
      delete static_cast<T
      >(t);
      }

      static void *Create(const void *t)
      {
          if (t)
              return new T(*static_cast<const T*>(t));
          return new T();
      }
      
      static void Destruct(void *t)
      {
          Q_UNUSED(t) // Silence MSVC that warns for POD types.
          static_cast<T*>(t)->~T();
      }
      
      static void *Construct(void *where, const void *t)
      {
          if (t)
              return new (where) T(*static_cast<const T*>(t));
          return new (where) T;
      }
      

      ....
      }
      @

      But its defined in a struct which is under QtMetaTypePrivate namespace, How should i use this ?

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lgeyer
        wrote on last edited by
        #3

        You shouldn't.

        Why do you want to use it in the first place?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sam
          wrote on last edited by
          #4

          In the above example "MyModule" class is derived from QFrame, and for my application i need to use a copy constructor , but since the copy constructor is DISABLED in the private section , it always returned "error: C2248: 'QFrame::QFrame' : cannot access private member declared in class 'QFrame'

          so in order to use that in Qt 4 i tried to use

          @template <>
          void *qMetaTypeConstructHelper<MyModule>(const MyModule *)
          {
          return new MyModule();
          }

          int MyModule::s_moduleID = qRegisterMetaType<MyModule>("MyModule");@

          but somehow while porting to Qt 5 the above template is not available i need to find an alternate solution to this.

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lgeyer
            wrote on last edited by
            #5

            The copy constructor is disabled for a reason (and the template specialization for qMetaTypeConstructHelper does not work as copy constructor; it just creates a <code>new MyModule</code> using the default constructor).

            So let's go back another step - why do you need a copy constructor in the first place?
            What is the problem you are trying to solve?

            If you are out for registering a non-copyable type with the meta type system don't, as the meta type system relies on a publicly available copy constructor (which is false for any QObject subclass). If you need to create a QObject by its name use a factory.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              Sam
              wrote on last edited by
              #6

              [quote author="Lukas Geyer" date="1358775900"]
              If you are out for registering a non-copyable type with the meta type system don't, as the meta type system relies on a publicly available copy constructor (which is false for any QObject subclass). If you need to create a QObject by its name use a factory.[/quote]

              You got it right, I actually want to create a QObject by its name, I too agree with using the facory implementation. Now I need to put the factory in place and test.

              Thanks for the reply.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                Sam
                wrote on last edited by
                #7

                I did some search and got an implementation of factory pattern :

                @#include <QMap>
                #include <QString>

                template<class Base> Base* new_object(const QString&);

                template<class Base>
                class Factory
                { // singleton class, one each base class
                Factory() {}
                Factory(const Factory&);
                Factory& operator=(const Factory&);
                ~Factory() { qDeleteAll(creators); }
                friend Base* new_object<>(const QString&);
                public:
                Base* create(const QString& nm) const
                {
                return (creators.contains(nm) ? creators[nm]->create() : NULL);
                }

                class Creator 
                { 
                public:
                    virtual ~Creator() {}
                    virtual Base* create() const = 0;
                };
                
                static Factory& instance() 
                {
                    static Factory p_instance;
                    return p_instance;
                }
                
                void unregisterCreator(const QString& nm) 
                {
                    if (creators.contains(nm)) 
                    {
                        delete creators[nm];
                        creators.remove(nm);
                    }
                }
                void registerCreator(const QString& nm, const Creator* c) 
                {
                    unregisterCreator(nm);
                    creators.insert(nm, c);
                }
                

                private:
                QMap<QString, const Creator*> creators;
                };

                template<class Base> Base* new_object(const QString& nm)
                {
                return Factory<Base>::instance().create(nm);
                }

                template<class Derived, class Base> class Register
                {
                typedef Derived* (*CreateFn) ();

                class Creator : public Factory&lt;Base&gt;::Creator 
                { 
                public:
                    Creator(CreateFn fn) : createFn(fn) {}
                    virtual Derived* create() const 
                    {
                        return (createFn ? createFn() : new Derived(NULL));
                    }
                    CreateFn createFn;
                };
                

                public:
                Register(const QString& nm, CreateFn fn = NULL)
                {
                Factory<Base>::instance().registerCreator(nm, new Creator(fn));
                }
                };@

                To create an instance we can use

                @Factory<QObject>::instance().create("RegisterMe")@

                or

                @QObject *o = new_object<QObject>("RegisterMe");@

                See "Simple-yet-powerful-object-factory":http://www.qtcentre.org/threads/8714-Simple-yet-powerful-object-factory

                There is another implementation provided by you at "Elegant factory design":http://qt-project.org/forums/viewthread/21540 discussion.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved