simple question

M

mosfet

Hi,

I have a question regarding derived class, let' say I have a base class
class PimItem

// A MS COM interface : for people who don't know com it's an interface
struct IDispatch
{
...
};

// Smart COM pointers(interface)
// IContact derives from IDispatch
typedef CComQIPtr<IDispatch> IDispatchPtr;
typedef CComQIPtr<IContact,&__uuidof(IContact)> IContactPtr;


class PimItem
{
public:

PimItem(CComQIPtr<IDispatch> pIItem) {m_pIItem = pIItem};
virtual ~PimItem();

protected:

CComQIPtr<IDispatch> m_pIItem; // Smart pointer pointing to a COM interface
}


class Contact : public PimItem
{
public:

void set_Foo(...) { static_cast<IContactPtr> (m_pIItem)->set_Foo() }
void set_Fire(...) {static_cast<IContactPtr> (m_pIItem)->set_Fire() }

protected:



};



As you can see in the contact class ,everytime I want to access a
function I need to cast my base pointer to my derived base.
In this case wouln'd be easier to remove m_pIItem inside base class and
directly store the right pointer type inside my derived one ?
 
A

Alf P. Steinbach

* mosfet:
Hi,

I have a question regarding derived class, let' say I have a base class
class PimItem

// A MS COM interface : for people who don't know com it's an interface
struct IDispatch
{
...
};

// Smart COM pointers(interface)
// IContact derives from IDispatch
typedef CComQIPtr<IDispatch> IDispatchPtr;
typedef CComQIPtr<IContact,&__uuidof(IContact)> IContactPtr;


class PimItem
{
public:

PimItem(CComQIPtr<IDispatch> pIItem) {m_pIItem = pIItem};
virtual ~PimItem();

protected:

CComQIPtr<IDispatch> m_pIItem; // Smart pointer pointing to a COM
interface
}


class Contact : public PimItem
{
public:

void set_Foo(...) { static_cast<IContactPtr> (m_pIItem)->set_Foo() }
void set_Fire(...) {static_cast<IContactPtr> (m_pIItem)->set_Fire() }

protected:



};



As you can see in the contact class ,everytime I want to access a
function I need to cast my base pointer to my derived base.
In this case wouln'd be easier to remove m_pIItem inside base class and
directly store the right pointer type inside my derived one ?

Yes, but presumably PimItem provides some more functionality than simply
holding that pointer (otherwise it's a useless class, to be removed),
and presumably that functionality depends on having access to the pointer.

And one solution is then to provide a pure virtual function that
produces the pointer.

Like

class Item
{
protected:
virtual Foo* fooPtr() const = 0;
public:
void doStuff() { gnurgle( fooPtr() ); }
};

class ContactItem: public GeneralItem
{
private:
FooSubclass* myFoo;
protected:
FooSuclass* fooPtr() const { return myFoo; }
public:
void doSpecificStuff() { gargle( fooPtr() ); }
};

Note that ContactItem::fooPtr overrides (and implements) Item::fooPtr,
even though the result type is more specific.

We say that the ContactItem::fooPtr is a covariant override.

C++ does not, however, support covariance for other types than pointers
and references, and in particular, it doesn't support covariance for
smart pointers, which are just class instances.

With smart pointers, as you have in your code, you have to emulate
covariance, like

typedef SmartPtr<Foo> PFoo;

class Item
{
protected:
virtual PFoo fooPtr() const = 0;
public:
void doStuff() { gnurgle( fooPtr() ); }
};

typedef SmartPtr<FooSubclass> PFooSubclass;

class ContactItem: public GeneralItem
{
private:
PFooSubclass myFoo;
protected:
PFoo fooPtr() const { return fooSubclassPtr(); }
virtual PFooSubclass fooSubclassPtr() const { return myFoo; }
public:
void doSpecificStuff() { gargle( fooSubclassPtr() ); }
};

Not a single cast in sight...

Cheers, and hth.,

- Alf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,290
Messages
2,571,453
Members
48,129
Latest member
DianneCarn

Latest Threads

Top