[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Smart Pointers and virtual

mosfet

8/18/2008 9:07:00 AM

Hi,

I am trying to modify existing code to use smart pointers and I get some
issues with virtual methods :

class Folder : public Object
{
public:
friend class PimItemCollection;
friend class ContactCollection;
friend class TaskCollection;
friend class AppointmentCollection;

// Constructor/destructor
Folder(OutlookSession* pOutlookSession) = 0;
virtual ~Folder();

virtual RefPtr<PimItemCollection> get_Items();

protected:
....
};



class ContactFolder : public Folder
{
public:
// Constructor/destructor
ContactFolder(OutlookSession* pOutlookSession);
ContactFolder();

virtual ~ContactFolder();

virtual RefPtr<ContactCollection> get_Items();
};

1>c:\testpoom\System.WindowsMobile.PocketOutlook.h(640) : error C2555:
'System::WindowsMobile::PocketOutlook::ContactFolder::get_Items':
overriding virtual function return type differs and is not covariant
from 'System::WindowsMobile::PocketOutlook::Folder::get_Items'

I Don't understand the error because ContactCollection is inheriting
from PimItemCollection.








2 Answers

Alf P. Steinbach

8/18/2008 9:26:00 AM

0

* mosfet:
> Hi,
>
> I am trying to modify existing code to use smart pointers and I get some
> issues with virtual methods :
>
> class Folder : public Object
> {
> public:
> friend class PimItemCollection;
> friend class ContactCollection;
> friend class TaskCollection;
> friend class AppointmentCollection;
>
> // Constructor/destructor
> Folder(OutlookSession* pOutlookSession) = 0;
> virtual ~Folder();
>
> virtual RefPtr<PimItemCollection> get_Items();
>
> protected:
> ...
> };
>
> class ContactFolder : public Folder
> {
> public:
> // Constructor/destructor
> ContactFolder(OutlookSession* pOutlookSession);
> ContactFolder();
>
> virtual ~ContactFolder();
>
> virtual RefPtr<ContactCollection> get_Items();
> };
>
> 1>c:\testpoom\System.WindowsMobile.PocketOutlook.h(640) : error C2555:
> 'System::WindowsMobile::PocketOutlook::ContactFolder::get_Items':
> overriding virtual function return type differs and is not covariant
> from 'System::WindowsMobile::PocketOutlook::Folder::get_Items'
>
> I Don't understand the error because ContactCollection is inheriting
> from PimItemCollection.

Presumably it was covariant before you added 'RefPtr'.

In that case, 'ContactCollection' is derived from 'PimItemCollection'.

And what you have now is an override with same arguments (none) and different
return type, 'RefPtr<Derived>' is typewise unrelated to 'RefPtr<Base>'.

Regarding the technical, in 'ContactFolder' you do it like this

virtual RefPtr<PimItemCollection> get_Items()
{
return get_contactCollection();
}

virtual RefPtr<ContactCollection> get_contactCollection() { ... }

Regarding design, though, since those collections do not seem to be read only
you're probably into typing problems. Let's say I'm using a Folder object to
retrieve a PimItemCollection. It's actually a ContactCollection but I'm treating
it as a generic PimItemCollection and I insert a PimItem that's not a Contact
but some other specific PimItem.

With the above design that error can only be caught at run-time.

Assuming this to be the case, be glad you got this covariance problem, exposing
the more important design problem! :-)


Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

kwikius

8/18/2008 10:05:00 AM

0

mosfet wrote:
> Hi,
>
> I am trying to modify existing code to use smart pointers and I get some
> issues with virtual methods :
>
> class Folder : public Object
> {
> public:
> friend class PimItemCollection;
> friend class ContactCollection;
> friend class TaskCollection;
> friend class AppointmentCollection;
>
> // Constructor/destructor
> Folder(OutlookSession* pOutlookSession) = 0;
> virtual ~Folder();
>
> virtual RefPtr<PimItemCollection> get_Items();
>
> protected:
> ...
> };
>
>
>
> class ContactFolder : public Folder
> {
> public:
> // Constructor/destructor
> ContactFolder(OutlookSession* pOutlookSession);
> ContactFolder();
>
> virtual ~ContactFolder();
>
> virtual RefPtr<ContactCollection> get_Items();
> };
>
> 1>c:\testpoom\System.WindowsMobile.PocketOutlook.h(640) : error C2555:
> 'System::WindowsMobile::PocketOutlook::ContactFolder::get_Items':
> overriding virtual function return type differs and is not covariant
> from 'System::WindowsMobile::PocketOutlook::Folder::get_Items'
>
> I Don't understand the error because ContactCollection is inheriting
> from PimItemCollection.

Unfortunately this is a problem with smart pointers in replacing raw
pointers.

When overrriding virtual functions one can modify the result type in
the override to a derived class of the return in the interface class,
known as covariant return. Unfortunately this doesnt translate if you
change to smart pointer as smart pointer to derived is not a derived
class of smart pointer to base (though it is convertible), but is a
separate class, so there is no covariant mechanism.

All you can do is change sig to base class, smart pointer return
expression in body should be automatically converted , but you then may
have to downcast again at other places in code, if you use derived class
direct, though myself I have found this rare in practise. Perhaps
covariant return is a case of being too clever anyway, breaks encapsulation

regards
Andy Little