Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, July 2007
QList and Abstract Base Classes


Message 1 in thread

Hello,
Short Question: Is there any way to have a QList of classes with pure
virtual functions?

Explanation:
I have an abstract base class called Product which is just a bunch of
pure virtual functions. Two other classes--DBProduct and
ManualProduct--inherit from Product and implement its pure virtual
functions. It sort of looks like this:
class Product {
  public:
    QString name() = 0;
}

class DBProduct : Product {
  public:
    QString name(); // pulls from DB
}

class ManualProduct : Product {
  public:
    QString name(); // pulls from var
}

In my invoice class, I want to have a QList<Product> to keep the
different products in.

The compiler obviously chokes when compiling because it can't create T
(Product). The warnings look something like this:
qlist.h:332: error: cannot allocate an object of type `Product'
qlist.h:332: error: because the following virtual functions are abstract:
product.h:34: error: virtual QString Category::name()
qlist.h:335: error: cannot allocate an object of type `Product'
qlist.h:335: error: since type `Product' has abstract virtual functions

FYI, this is Qt 4.3.0, and the lines from qlist.h:
Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src)
{
    if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
        while(from != to)
            (from++)->v = new T(*reinterpret_cast<T*>((src++)->v)); // 332
    else if (QTypeInfo<T>::isComplex)
        while(from != to)
            new (from++) T(*reinterpret_cast<T*>(src++)); //335

Any ideas about how to work around this? I don't want to store
pointers in my QList, because that just ends up being a mess (deleting
them, that is).

Thanks!
- Taj

-- 
 [ signature omitted ] 

Message 2 in thread

Try QList<Product*>

Scott

> -----Original Message-----
> From: Taj Morton [mailto:tajmorton@xxxxxxxxx]
> Sent: Monday, July 02, 2007 7:49 PM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: QList and Abstract Base Classes
> 
> Hello,
> Short Question: Is there any way to have a QList of classes with pure
> virtual functions?
> 
> Explanation:
> I have an abstract base class called Product which is just a bunch of
> pure virtual functions. Two other classes--DBProduct and
> ManualProduct--inherit from Product and implement its pure virtual
> functions. It sort of looks like this:
> class Product {
>   public:
>     QString name() = 0;
> }
> 
> class DBProduct : Product {
>   public:
>     QString name(); // pulls from DB
> }
> 
> class ManualProduct : Product {
>   public:
>     QString name(); // pulls from var
> }
> 
> In my invoice class, I want to have a QList<Product> to keep the
> different products in.
> 
> The compiler obviously chokes when compiling because it can't create T
> (Product). The warnings look something like this:
> qlist.h:332: error: cannot allocate an object of type `Product'
> qlist.h:332: error: because the following virtual functions are
abstract:
> product.h:34: error: virtual QString Category::name()
> qlist.h:335: error: cannot allocate an object of type `Product'
> qlist.h:335: error: since type `Product' has abstract virtual
functions
> 
> FYI, this is Qt 4.3.0, and the lines from qlist.h:
> Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node
> *src)
> {
>     if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
>         while(from != to)
>             (from++)->v = new T(*reinterpret_cast<T*>((src++)->v)); //
332
>     else if (QTypeInfo<T>::isComplex)
>         while(from != to)
>             new (from++) T(*reinterpret_cast<T*>(src++)); //335
> 
> Any ideas about how to work around this? I don't want to store
> pointers in my QList, because that just ends up being a mess (deleting
> them, that is).
> 
> Thanks!
> - Taj
> 
> --
> Taj
> http://www.wildgardenseed.com/Taj/blog
> 
> Need a GMail invite? Email me.
> Peace cannot be kept by force; it
> can only be achieved by understanding.
>                 -- A. Einstein
> 
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/

--
 [ signature omitted ] 

Message 3 in thread

Scott Aron Bloom wrote:

>> Any ideas about how to work around this? I don't want to store
>> pointers in my QList, because that just ends up being a mess (deleting
>> them, that is).

You don't get a choice, really. QList is a value container and isn't
directly useful for polymorphic types.

If your Product type had no pure virtual methods and had a public ctor,
the compiler would let you create a QList<Product> but you would instead
have other problems. Whenever you inserted a SpecificKindOfProduct into
a QList<Product> it'd be _sliced_ down to just a Product. All the
special behaviour and data associated with the SpecialKindOfProduct
would be discarded. This is probably not what you wanted.

It's much like saying:

SpecialKindOfProduct sp;
Product p = sp;

... in that sp is truncated down to sizeof(Product). Whoops.

It may be possible to use a smart pointer class to contain your Product
subclass instances in a QList. You'd have to make sure the smart pointer
satisfies the interface and behavioural requirements for a container
item type, though.

Personally I'd either just use a QList<Product*> (well, usually
list<Product*> for me) and manage allocations directly, or if the
structure was widely used and visible I'd wrap the internal QList in a
class that owned the items it contained and took care of their
destruction for me.

It's not pretty, but polymorphic types in containers are IMO one of the
uglier aspects of C++. It's not really going to be pretty no matter what
you do.

--
 [ signature omitted ] 

Message 4 in thread

Scott Aron Bloom wrote:
> 
>> Any ideas about how to work around this? I don't want to store
>> pointers in my QList, because that just ends up being a mess (deleting
>> them, that is).

The porting notes for QPtrList might provide some interesting
information for you too:

http://doc.trolltech.com/4.3/porting4.html#qptrlist-t

--
 [ signature omitted ]