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?
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