Home > Mobile >  c best way to reset whole class with virtual dtor
c best way to reset whole class with virtual dtor

Time:06-14

I'm trying to reset a full class with a virtual dtor. Class Foo has lot's of data members, it would be easier to reset them all at once

class Foo : public QOject
{
  public:
    Foo() = default;

    Foo(Foo&& rhs) = default;

    Foo(Foo& rhs) = default;


    Foo& operator=(const Foo& rhs) = default;

    Foo& operator=(Foo&& rhs) = default;
  private:
  ///lots of data members here
}

Since QOject has a virtual dtor no default constructors/operators are generated for Foo When calling

mg_foo = Foo();

the compiler fails to generate a copy operator because QObject has virtual functions

I can't use pointers as well since at application startup I'm passing a raw address to QML

QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("foo", &mg_foo);

If I use a pointer and change the address of mg_foo at runtime (with a brand new initialised class) my application crashes.

How would you handle such problem?

thx for your help :)

CodePudding user response:

Check the QT documentation for the QObject class:

QObject has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private. The reasoning is found in the discussion on Identity vs Value on the Qt Object Model page.

The main consequence is that you should use pointers to QObject (or to your QObject subclass) where you might otherwise be tempted to use your QObject subclass as a value. For example, without a copy constructor, you can't use a subclass of QObject as the value to be stored in one of the container classes. You must store pointers.

So the compiler will fail to generate the copy and assignment operators no matter what you do. You might also want to note that the QObject's only constructor is QObject::QObject(QObject* parent=nullptr). Looking at the documentation, this means that every instance of Foo you create (with your compiler-generated default constructor) will be a top-level window.

As for what to do regarding "resetting" the class, you will have to be more specific about what you are looking for there.

CodePudding user response:

If I understand the problem well, resetting the many data members should be very easy. Just put all the "many" data members to a private data class/struct.

class Foo : public QObject
{
public:
  // ... public stuff

  void reset();

private:
  struct FooPrivate
  {
    // all the "many" data members with their default values
  };

  FooPrivate m_data;
};

void Foo::reset()
{
  m_data = FooPrivate{}; // this resets the data
}

Yes the drawback is that you have to access all the members via m_data. But it is the price you pay for that you can reset the data in one line.

Btw. If I had too many data members in my class I would think twice about the design. It suggests that the class may have too much responsibility. And you know the rules: one class, one responsibility. Maybe you should change the overall design and split the class into two or more.

  •  Tags:  
  • c qt
  • Related