Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9157921
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T13:07:59+00:00 2026-06-17T13:07:59+00:00

Background: I have my class called ObjectListModel which inherits QAbstractListModel and contains a QObjectList

  • 0

Background:

  • I have my class called ObjectListModel which inherits QAbstractListModel and contains a QObjectList. The objects are rows and their properties are columns (set using a QMetaObject), and notifcation changes are propagated to views. There’s also some container helpers (begin/end/iterator/size) so that I can iterate through the QObject’s stored.
  • I also have a TypedObjectListModel<T>, which provides type-safety (mainly by overriding push_back et.al. with and defining new iterator types that do static_cast to T).

This all works very well when I only have one type of objects. I just create new class (f.ex. FruitsModel, which has Q_OBJECT in it, and inherits TypedObjectListModel<Fruit>. This can only contain Fruits or Fruit-subobjects.

However, I now have an app can that run in two different states. In the second state the model should only hold Apples, no Bananas (or Fruits for that matter, which is a concrete base class).

So, I’d like to create an ApplesModel type, that should inherit FruitsModel and just change the type of T. This gets me into trouble, because I get the inheritance diamond OF DEATH:

 QObject
       |
 QAbstractListModel
       |
 ObjectListModel -------------------
       |                           |
 TypedObjectListModel<Fruit>     TypedObjectListModel<Apple>
       |                           |
 FruitsModel  -------------------ApplesModel

This is also conceptually wrong, since FruitsModel::push_back(Fruit*) is illegal in ApplesModel. However, reading/iterating over Fruits (not just Apples) should be possible.

Also, I have some functions in FruitsModel (findFruitById) that should be overriden and only return Apples in ApplesModel.

What is the preferred design pattern in solving this problem in C++?

I suspect (hope) I’m not the first trying to do something similar.

I’ve tried lots of ideas but I get stuck in various dead ends. You’d think virtual inheritance of ObjectListModel would solve the problem, but then I get this using QObject::findChild:

error C2635: cannot convert a 'QObject*' to a 'ApplesModel*'; conversion from a virtual base class is implied

The above can be remedied with my own implementation of findChild, using dynamic_cast instead, but there are still some dead-ends.

template<typename T>
inline T myFindChild(const QObject *parent, const QString &name = QString())
{ 
    return dynamic_cast<T>(qt_qFindChild_helper(parent, name, reinterpret_cast<T>(0)->staticMetaObject)); 
}

UPDATE

geekp had the following suggestions:

Inherit Apple from Fruit and don’t bother with ApplesModel

How do I then enforce that only apples are in the FruitsModel? Also, I
need to downcast every-time I fetch an apple (as fruit).

Don’t inherit from FruitsModel (why would you if you are not using it’s
methods?)

I’m using some methods, notably so the ones for reading.

Don’t inherit from TypesObjectListModel of Apple and subclass only FruitsModel.

Same drawbacks as not bothering with AppleModel.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T13:08:01+00:00Added an answer on June 17, 2026 at 1:08 pm

    So reading and writing operations are fundamentally different with regards to inheritance.

    Going back to OOP 101, remember the parable about the square and the rectangle? It is often said that the square is a kind of rectangle, but that is only true when reading.

    When writing, squares are not kinds of rectangles, but rectangles are kinds of squares!

    Ie:

    bool test( Rectangle* r ) {
      int old_height = r->GetHeight();
      int old_width = r->GetWidth();
      r->SetWidth(old_width+100);
      return old_height == r->GetHeight();
    }
    

    the above function returns true for all “real” rectangles, but for Squares it might not. So the contracts around SetWidth that are reasonable for Rectangle is violated for Square.

    On the other hand, every interface for Rectangle that is read-only is perfectly handled by Square.

    This might give you a mess like this:

    struct IRectangleRead { ... };
    struct ISquareRead { ... };
    
    struct ISquareWrite: virtual ISquareRead { ... };
    struct IRectangleWrite:ISquareWrite, virtual IRectangleRead { ... };
    
    struct ConstRectangle: virtual IRectangleRead { ... };
    struct ConstSquare: virtual ISquareRead, virtual IRectangleRead { ... };
    
    struct Rectangle: ConstRectangle, IRectangleWrite { ... };
    struct Square: ConstSquare, ISquareWrite { ... };
    

    which generates a mess of an inheritance hierarchy, but one where restrictive contracts can be placed on each method, and every object that implements the method will obey them.

    Now, you should note that the above becomes ridiculously easier if your objects are immutable. Then the only form of writing is via factory functions, and things become tidy.

    So the concrete lesson here — split the reading and modifying parts of your code. The common modifying part (that works on the base classes) isn’t publicly exposed, because the operation is invalid in the subclass cases.

    The common reading part is publicly exposed, as is the subtype reading part.

    The subtype writing code forwards to the private common base class writing code.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a class called Timestamp. This class contains a static NSDate variable which
I have a background worker which calls a function within a separate class. This
I have a css class called navigation which will hold some link and when
Background In my utilities library (Shd.dll) I have a class called AsyncOperation. To put
The background... Lets say I have a class called cars. We are just going
Say I have a class named testThing: .testThing { background-color:#000000; float:left; height:50px; width:50px; }
I have an IValueConverter class that is used to change the background color of
I have a helper class that should only ever run in a background thread.
I basically have the following class: .sf-sub-indicator { background: url(/abcprod/images/arrows-ffffff.png) no-repeat -10px -100px; }
lets say i have a background worker in a class that perform db query

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.