| View previous topic :: View next topic |
| Author |
Message |
Eduardo Bezerra Guest
|
Posted: Sun Nov 27, 2005 5:56 pm Post subject: Polymorphism and Template Based Design |
|
|
Hi,
I'm trying to come up with a solution based on templates
that could reproduce the same semantics of the example
below:
struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Any help would be greatly appreciated.
Best regards,
Eduardo
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bob Hairgrove Guest
|
Posted: Sun Nov 27, 2005 9:52 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
On 27 Nov 2005 12:56:56 -0500, "Eduardo Bezerra" <edubez (AT) gmail (DOT) com>
wrote:
| Quote: | Hi,
I'm trying to come up with a solution based on templates
that could reproduce the same semantics of the example
below:
struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Any help would be greatly appreciated.
Best regards,
Eduardo
|
In your example, you don't actually do anything with these ... not
sure what you had in mind. Why do you think it is necessary to use
templates?
Otherwise, you have leaked memory because pConcreteA and pConcreteB
are never deleted. Also, Intf should have a virtual destructor if you
intend to delete either of the derived objects through an Intf*, else
you have undefined behavior.
--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
peter steiner Guest
|
Posted: Sun Nov 27, 2005 9:54 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
Eduardo Bezerra wrote:
| Quote: | Hi,
I'm trying to come up with a solution based on templates
that could reproduce the same semantics of the example
below:
struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
|
your example basically just utilizes the storage of polymorphic
pointers into a common base type pointer. with static polymorphism
(through templates) there is no direct equivalent of "common base
type". polymorphism depends on the assumption that different classes of
the same type share a specific common interface, while the concrete
type of statically polymorph objects in reality has no connection at
all (in the sense of type in C++).
you would have to work around that limitation in a way like the
following:
struct ConcreteA {
void Fun() {
}
};
struct ConcreteB {
void Fun() {
}
};
template <typename ConcreteType>
struct Base {
const ConcreteType& obj;
Base(const ConcreteType& obj) : obj(obj) {}
void Fun() { obj.Fun(); }
};
template <typename ConcreteType>
void processConcreteObject(ConcreteType& concrete)
{
Base<ConcreteType> base(concrete);
// ...
}
int main()
{
ConcreteA concreteA;
ConcreteB concreteB;
processConcreteObject(concreteA);
processConcreteObject(concreteB);
}
storing both ConcreteA and ConcreteB into a single variable as in your
example is only possible with serious drawbacks with static
polymorphism..
-- peter
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Mon Nov 28, 2005 8:19 am Post subject: Re: Polymorphism and Template Based Design |
|
|
Eduardo Bezerra wrote:
| Quote: | Hi,
I'm trying to come up with a solution based on templates
that could reproduce the same semantics of the example
below:
struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
|
As I understand the question: the problem is how to declare a single
pointer that can point to an object of any type just as long as that
type implements a void Fun() method.
Since we already have a model of how we would like things to work, I
would simply adopt that model for a a class template:
First, declare the common interface:
struct Intf
{
virtual void Fun() = 0;
};
Next, declare a class template that adheres to this interface and that
also wraps an object of the targeted type. Invoking Fun() through an
instance of this template class, invokes the Fun() method of the
wrapped object:
template <class T>
struct ObjectInterface : public Intf
{
ObjectInterface(T* t) : t_( t)
{
}
// TODO: add copy constructor, assignment operator
virtual ~ObjectInterface()
{
delete t_;
}
virtual void Fun()
{
t_->Fun();
}
private:
T *t_;
};
Now the program is able to instantiate ObjectInterface<ConcreteA> and
ObjectInterface<ConcreteB> objects and treat a pointer to either one as
an Intf pointer. Calling the Fun() method through the Inft pointer
calls the appropriate Fun() method in the target type. ConcreteA and
ConcreteB need only to implement a Fun() method, they need not
otherwise be related.
int main()
{
// ConcreteA and ConcreteB can be unrelated types
// as long as each implements a void Fun() method
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = new ObjectInterface<ConcreteA>(pConcreteA);
pIntf->Fun(); // calls through to ConcreteA::Fun();
delete pIntf;
pIntf = new ObjectInterface<ConcreteB>(pConcreteB);
pIntf->Fun(); // calls through to ConcreteB::Fun();
delete pIntf;
}
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Eduardo Bezerra Guest
|
Posted: Mon Nov 28, 2005 8:24 am Post subject: Re: Polymorphism and Template Based Design |
|
|
Yes I know about the virtual destructor and the delete, but it's just a
contrived code snippet.
My intention is to see if it's possible to reproduce the semantics of
a polymorphic pointer to base using some template technique. I could
use the solution to implement, for example, some design patterns like
State or Strategy.
I'm actually looking for template based implementations of the State
Pattern.
Regards,
Eduardo
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mateusz Loskot Guest
|
Posted: Mon Nov 28, 2005 3:53 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
Eduardo Bezerra napisal(a):
| Quote: |
My intention is to see if it's possible to reproduce the semantics of
a polymorphic pointer to base using some template technique.
|
I'd recommend you to read following chapters:
"14. The Polymorphic Power of Templates"
"14.1 Dynamic Polymorphism"
"14.2 Static Polymorphism"
"14.3 Dynamic versus Static Polymorphism"
from the great book "C++ Templates: The Complete Guide" by David
Vandevoorde, Nicolai M. Josuttis
After you read it you will be able to recognize when it is and when it
is not possible to switch between both types of polymorphisms.
Cheers
--
Mateusz Loskot
http://mateusz.loskot.net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
ben Guest
|
Posted: Mon Nov 28, 2005 4:27 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
| Quote: | struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
|
I think you are trying to achieve static polymorphism? This involves
informing the compiler the exact type of the object to operate. Just for
an example:
template <typename T>
void Fun(T* ptr)
{
ptr->Fun();
}
ConcreteA a;
ConcreteB b;
Fun(&a); // equivalent to a->Fun()
Fun(&b); // equivalent to b->Fun()
Remember that if you need to abstract the exact type information then
virtual function is the solution to go.
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dan McLeran Guest
|
Posted: Mon Nov 28, 2005 4:29 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
You should check out Andrei's book, 'Modern C++ Design' for a great
tutorial on using templates to implement design patterns.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Axter Guest
|
Posted: Mon Nov 28, 2005 9:06 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
Greg Herlihy wrote:
| Quote: | Eduardo Bezerra wrote:
Hi,
I'm trying to come up with a solution based on templates
that could reproduce the same semantics of the example
below:
struct Intf {
virtual void Fun() = 0;
};
struct ConcreteA : Intf {
void Fun() {
}
};
struct ConcreteB : Intf {
void Fun() {
}
};
int main()
{
ConcreteA* pConcreteA = new ConcreteA;
ConcreteB* pConcreteB = new ConcreteB;
Intf* pIntf;
pIntf = ConcreteA;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
pIntf = ConcreteB;
//^^^^^^^^^^^^^^^^^^^^^^^^^^
}
As I understand the question: the problem is how to declare a single
pointer that can point to an object of any type just as long as that
type implements a void Fun() method.
|
You can do this by creating a Heterogeneous wrapper class.
Check out the following links for example code:
http://code.axter.com/HeterogeneousContainer1.cpp
http://code.axter.com/HeterogeneousContainer2.cpp
http://code.axter.com/HeterogeneousContainer3.cpp
The above links are listed from simple to complex, with the last
version having a wrapper that can allow the function name to vary.
With a good Heterogeneous wrapper, you don't need to have a common base
class for the target object, and you don't need to have a common
function name for the target object, because the Heterogeneous wrapper
class hides the details.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mateusz Loskot Guest
|
Posted: Tue Nov 29, 2005 10:19 am Post subject: Re: Polymorphism and Template Based Design |
|
|
Hi Axter,
I see Heterogeneous wrapper for the first time. I like it but I'd like
to read more about it.
Could you point me to any materials on the Web or book about it?
Cheers
--
Mateusz Loskot
http://mateusz.loskot.net
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Axter Guest
|
Posted: Wed Nov 30, 2005 7:45 pm Post subject: Re: Polymorphism and Template Based Design |
|
|
Mateusz Loskot wrote:
| Quote: | Hi Axter,
I see Heterogeneous wrapper for the first time. I like it but I'd like
to read more about it.
Could you point me to any materials on the Web or book about it?
Cheers
|
Unfortunately, I haven't found any literature on the subject.
Most of the information I've read on it has come from the newsgroup
and web base C++ forums like www.experts-exchange.com and
www.codeguru.com.
If you do a keyword search on "Heterogeneous class wrapper",
you'll turn up a few links, but they're not all that great.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|