Simple OO design issue

O

obrianpatrick

Hi,

I am relatively new to object oriented programming and design. I am
developing an application in VS 2005. I am having the following design
problem:

I have two interfaces X and Y. Y is derived from X as the following:

__interface X
{
public:
virtual void func1(int) = 0;
};

__interface Y: public X
{
public:
virtual void func2(int) = 0;
};

X interface is implemented in the class XImpl as follow:

class XImpl: public X
{
public:
void func1(int i)
{
cout << "In XImpl::func 1: i = " << i;
}
};


Now I want to have a class YImpl implementing func2() of Y interface.
func1 implementation should remain the same as in XImpl. How should I
define the class YImpl? Deriving it only from Y interface, as

class YImpl: public Y

will not allow me to use the func1() implementation of XImpl. I have
to rewrite the same function in YImpl then.

On the other hand inheriting YImpl multiply from XImpl and Y as

as

class YImpl: public XImpl, public Y

is not a good idea as X interface is included twice (and the VC++
complier is not allowing it either, rightly complaining that func1 is
ambiguous).

How should the class YImpl be defined and implemented? Please note
that I can change the definition or implementation of XImpl but not
the definition of X and Y interfaces as they have come from some other
sources on which I have no control.

Thanks in advance,
Patrick O'Brian
 
S

Stuart Redmann

Hi,

I am relatively new to object oriented programming and design. I am
developing an application in VS 2005. I am having the following design
problem:

I have two interfaces X and Y. Y is derived from X as the following:

__interface X
{
public:
virtual void func1(int) = 0;
};

__interface Y: public X
{
public:
virtual void func2(int) = 0;
};

Common scenario.
X interface is implemented in the class XImpl as follow:

class XImpl: public X
{
public:
void func1(int i)
{
cout << "In XImpl::func 1: i = " << i;
}
};
Okay.

Now I want to have a class YImpl implementing func2() of Y interface.
func1 implementation should remain the same as in XImpl. How should I
define the class YImpl? Deriving it only from Y interface, as

class YImpl: public Y

will not allow me to use the func1() implementation of XImpl. I have
to rewrite the same function in YImpl then.

On the other hand inheriting YImpl multiply from XImpl and Y as

as

class YImpl: public XImpl, public Y

is not a good idea as X interface is included twice (and the VC++
complier is not allowing it either, rightly complaining that func1 is
ambiguous).

How should the class YImpl be defined and implemented? Please note
that I can change the definition or implementation of XImpl but not
the definition of X and Y interfaces as they have come from some other
sources on which I have no control.

You have stumbled over some implementation issues that come together with
interface programming (when using some component architecture). The standard
solution to your problem is to make the implementation class XImpl a template:

template<class t_BaseInterface>
class XImpl : public t_BaseInterface
{
public:
void func1(int i)
{
// Implementation of func1 of interface X
}
};

If you want to use XImpl for implementing, you have to use it like XImpl<X> (or
you can make X the default base interface for XImpl like template <class
t_BaseInterface = X>, than you can say XImpl<> with empty template parameter list).
For YImpl you have to say:
class YImpl : public XImpl<Y>
{
....
};

Now XImpl implements the func1 of interface Y, and YImpl needs only to implement
func2.

Regards,
Stuart

BTW: If you cross-post to several newsgroups, you should rather specify a
follow-up newsgroup, so that any replies to your post are accumulated in a
single newsgroup.
 
I

Ian Collins

Hi,

I am relatively new to object oriented programming and design. I am
developing an application in VS 2005. I am having the following design
problem:

I have two interfaces X and Y. Y is derived from X as the following:

__interface X

Where does this come from, it ain't C++?
 
O

obrianpatrick

Hi Stuart,
Thanks a ton. How neat!!
Patrick

Common scenario.








You have stumbled over some implementation issues that come together with
interface programming (when using some component architecture). The standard
solution to your problem is to make the implementation class XImpl a template:

template<class t_BaseInterface>
class XImpl : public t_BaseInterface
{
public:
void func1(int i)
{
// Implementation of func1 of interface X
}

};

If you want to use XImpl for implementing, you have to use it like XImpl<X> (or
you can make X the default base interface for XImpl like template <class
t_BaseInterface = X>, than you can say XImpl<> with empty template parameter list).
For YImpl you have to say:
class YImpl : public XImpl<Y>
{
....

};

Now XImpl implements the func1 of interface Y, and YImpl needs only to implement
func2.

Regards,
Stuart

BTW: If you cross-post to several newsgroups, you should rather specify a
follow-up newsgroup, so that any replies to your post are accumulated in a
single newsgroup.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
 
B

Branimir Maksimovic

Where does this come from, it ain't C++?
It's microsoft specific extension to C++ language.
It is basically a class that enforces only public
pure virtual functions (disregarding if function
is not declared virtual)
, can inherit only from interface classes,
and also does not have vtable nor does initialize
vptr in order to reduce code size.
Commonly used for microsoft com programming.

Greetings, Branimir.
 
D

Daniel T.

How should the class YImpl be defined and implemented? Please note
that I can change the definition or implementation of XImpl but not
the definition of X and Y interfaces as they have come from some other
sources on which I have no control.

The appropriate C++ solution is that the person who wrote class Y should
have used virtual inheritance. Let him know of his bug.

Stuart's work around is a nice idea though...
 
N

Naresh Rautela

Common scenario.








You have stumbled over some implementation issues that come together with
interface programming (when using some component architecture). The standard
solution to your problem is to make the implementation class XImpl a template:

template<class t_BaseInterface>
class XImpl : public t_BaseInterface
{
public:
void func1(int i)
{
// Implementation of func1 of interface X
}

};

If you want to use XImpl for implementing, you have to use it like XImpl<X> (or
you can make X the default base interface for XImpl like template <class
t_BaseInterface = X>, than you can say XImpl<> with empty template parameter list).
For YImpl you have to say:
class YImpl : public XImpl<Y>
{
....

};

Now XImpl implements the func1 of interface Y, and YImpl needs only to implement
func2.

Regards,
Stuart

BTW: If you cross-post to several newsgroups, you should rather specify a
follow-up newsgroup, so that any replies to your post are accumulated in a
single newsgroup.- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Cool!!! Thats a very cool way of doing it. However, I have a feeling
that whenever you run in to such issues and have to resort to such
geeky way of doing things, it points to a design issue. Probably the
interface is not being used the way it was intended to be. Probably
we need a composition here rather than a inheritance (Class Z embeds
both class X and Y). Would really appreciate if someone out there
points out a scenario where such a construct is an absolute must.
 
D

Daniel T.

Naresh Rautela said:
Cool!!! Thats a very cool way of doing it. However, I have a feeling
that whenever you run in to such issues and have to resort to such
geeky way of doing things, it points to a design issue. Probably the
interface is not being used the way it was intended to be. Probably
we need a composition here rather than a inheritance (Class Z embeds
both class X and Y). Would really appreciate if someone out there
points out a scenario where such a construct is an absolute must.

Well yes, YImpl could contain an XImpl object and delegate to it, but
that would be effectively the same as Stuart's idea and take more typing.
 
B

Branimir Maksimovic

Cool!!! Thats a very cool way of doing it. However, I have a feeling
that whenever you run in to such issues and have to resort to such
geeky way of doing things, it points to a design issue. Probably the
interface is not being used the way it was intended to be. Probably
we need a composition here rather than a inheritance (Class Z embeds
both class X and Y). Would really appreciate if someone out there
points out a scenario where such a construct is an absolute must.

Well this is standard com issue, except that he should specify
__stdcall calling convention to produce valid COM objects.
For example, this is also perfectly legal way of doing it:
__interface X
{
void __stdcall func1(int);
};

__interface Y: X
{
void __stdcall func2(int);
};

struct XImpl
{
void* vptr;
int j;
static void __stdcall func1(XImpl*x,int i)
{
cout << "In XImpl::func 1: i = " << i;
x->j = i;
}
};

struct YImpl
{
XImpl x;
YImpl();
static void __stdcall func2(YImpl*y,int i)
{
cout << "In YImpl::func 2: i = " << i << " j = " << y->x.j;
}
};

typedef void (__stdcall *func_t)(YImpl*,int);

struct YImplVtable{
func_t func1,func2;
}vty = { (func_t)&XImpl::func1,&YImpl::func2 };

YImpl::YImpl(){x.vptr=&vty;}

and in program:

YImpl ii;
Y* y = (Y*)&ii;
y->func1(42);
y->func2(1);

Actually laying down objects and vtables is only way to
program COM objects in C. If C++ provides layout
compatibility it has convenient syntax.
Interfaces just provide vtable layout, can't be used for
casual C++ programming (no virtual destructors so user must
provide function for deletition, only public
non virtual inheritance allowed ...)

Greetings, Branimir.
 

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

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,286
Latest member
ChristieSo

Latest Threads

Top