472,365 Members | 1,218 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,365 software developers and data experts.

Mimic virtual functions with templates

Greetings

I want to have virtual member functionality, but without my member
functions
being virtual:-)

As of yet this is all just in my head cause I can't see a nice
solution yet so lets start with some simple code.
template <class T>
class Base
{
public:
void Func()
{
T* ptrT = static_cast<*T>(this);
pT->FuncImpl();
};
protected:
void FuncImpl() {std::cout << "This is Base"<<std::endl;}
};

class DerivedOne : public Base<DerivedOne>
{
public:
void FuncImpl() {std::cout <<"This is DerivedOne"<<std::endl; }
};

class DerivedTwo : public Base<DerivedTwo>
{
public:
void FuncImpl() {std::cout <<"This is DerivedTwo"<<std::endl; }
};

The thing I want to be able to todo is something like this

Base * b = GetSomeDerivedClass();
b->Func();

I'm quite sure this won't work as Base is a template class, but how
can I achieve something similar?
I recently read about someone wanting to store template classes of
different
types in an STL container, which is sort of similar to my problem and
one
of the suggestions was to use boost::any.
Is that the only suggestion if it is a solution at all?
Martin
Jul 22 '05 #1
4 1736
Martin wrote:
Greetings

I want to have virtual member functionality, but without my member
functions being virtual:-)
For which reason?
As of yet this is all just in my head cause I can't see a nice
solution yet so lets start with some simple code.
template <class T>
class Base
{
public:
void Func()
{
T* ptrT = static_cast<*T>(this);
pT->FuncImpl();
};
protected:
void FuncImpl() {std::cout << "This is Base"<<std::endl;}
};

class DerivedOne : public Base<DerivedOne>
{
public:
void FuncImpl() {std::cout <<"This is DerivedOne"<<std::endl; }
};

class DerivedTwo : public Base<DerivedTwo>
{
public:
void FuncImpl() {std::cout <<"This is DerivedTwo"<<std::endl; }
};

The thing I want to be able to todo is something like this

Base * b = GetSomeDerivedClass();
b->Func();

I'm quite sure this won't work as Base is a template class, but how
can I achieve something similar?
So you want to do dynamic dispatching, i.e. call a function, but decide at
runtime which one is actually to be called. In this case, you need some way
to dynamically find out the actual type of your object and then select the
function belonging to that type. The normal C++ way with virtual functions
is usually implemented as an extra hidden member variable that is a pointer
to a table of function pointers (called the vtable). Based on the type, the
according vtable is selected and based on the function you specified, the
table is indexed to find the pointer to that function. At least that's the
way that every compiler I know about uses.
Your template way doesn't work, because templates can only do static
dispatching, i.e. the actual function to be called is selected at compile
time.
I recently read about someone wanting to store template classes of
different types in an STL container, which is sort of similar to my
problem and one of the suggestions was to use boost::any.
Is that the only suggestion if it is a solution at all?


Well, boost::any uses a combination of templates and virtual member
functions, AFAIK. Why exactly would you need your solution to not use
virtual member functions?

Jul 22 '05 #2
You can get to about here:

class Dog {
public:
void sound() const { std::cout << "vuf!" << std::endl; };
};

class Cat {
public:
void sound() const { std::cout << "Miauw!" << std::endl; };
};

class Parrot {
public:
void sound() const { std::cout << "Squark!" << std::endl; };
};

template <class T> void makeNoise(const T& obj) {
obj.sound();
};

int main(int /*argc*/,char*[] /*argv*/)
{

makeNoise(Dog());
makeNoise(Cat());
makeNoise(Parrot());
return 0;
}

Or if you want your member functions truly dynamic, take a pointer to member
and store in a protected variable in the base class...

Sry. but I am not sure what the purpose for it is!!!?
"Martin" <pe*******@hotmail.com> wrote in message
news:9b**************************@posting.google.c om...
Greetings

I want to have virtual member functionality, but without my member
functions
being virtual:-)

As of yet this is all just in my head cause I can't see a nice
solution yet so lets start with some simple code.
template <class T>
class Base
{
public:
void Func()
{
T* ptrT = static_cast<*T>(this);
pT->FuncImpl();
};
protected:
void FuncImpl() {std::cout << "This is Base"<<std::endl;}
};

class DerivedOne : public Base<DerivedOne>
{
public:
void FuncImpl() {std::cout <<"This is DerivedOne"<<std::endl; }
};

class DerivedTwo : public Base<DerivedTwo>
{
public:
void FuncImpl() {std::cout <<"This is DerivedTwo"<<std::endl; }
};

The thing I want to be able to todo is something like this

Base * b = GetSomeDerivedClass();
b->Func();

I'm quite sure this won't work as Base is a template class, but how
can I achieve something similar?
I recently read about someone wanting to store template classes of
different
types in an STL container, which is sort of similar to my problem and
one
of the suggestions was to use boost::any.
Is that the only suggestion if it is a solution at all?
Martin

Jul 22 '05 #3
Well I guess I should explain myself.

I have a "packet decoder" that uses the Strategy pattern.
There's a hash_map which maps packet types to PacketDecoders(which all
inherits from AbstractDecoder).

struct AbstractDecoder
{
virtual UInt16 Decode(Byte *pBuf, UInt16 iBufSize) = 0;
};
struct SpecialDecoderOne : public AbstractDecoder
{
virtual UInt16 Decode(Byte *pBuf, UInt16 iBufSize)
{
std::cout << "Decoding message type 1"<<std::endl;
return 1;
}
};

typedef stdext::hash_map<const
UInt16,AbstractDecoder*,std::equal_to<UInt16> > DecoderStrategy;
typedef DecoderStrategy::const_iterator Iter;

DecoderStrategy decoders;

//here we relay the decoding to the special packet decoder.
UInt16 PacketHandler::Decode(UInt16 type, Byte *pBuf, UInt16 iBufSize)
{
Iter iter, end = decoders.end();
if((iter = decoders.find(type)) != end)
{
return *iter->Decode(pBuf, iBufSize);
}
throw PacketDecoderNotFoundException(type);
}

I'd ultimately like to lose the virtual functions by using the inherit
from template parameter trick

template <class T>
class AbstractDecoder
{
public:
UInt16 Decode(Byte *pBuf, UInt16 iBufSize)
{
T *pT = static_cast<T*>(this);
return pT->DecodeImpl(pBuf, iBufSize);
}
protected:
UInt16 DecodeImpl(Byte *pBuf, UInt16 iBufSize)
{
std::cout <<"OOPS no DecodeImpl in subclass"<<std::endl;
}
};

struct SpecialDecoderOne : public AbstractDecoder<SpecialDecoderOne>
{
UInt16 DecodeImpl(Byte *pBuf, UInt16 iBufSize)
{
std::cout << "Decoding message type 1"<<std::endl;
return 1;
}
};

The reason to this is I want the decoder to be as efficient as
possible short
of doing a big switch(type) over all the different packets.

I will accept if it's not possible to achieve this in anyway though
:-)

edit: please overlook any missing "const" :-P
Jul 22 '05 #4
//here we relay the decoding to the special packet decoder.
UInt16 PacketHandler::Decode(UInt16 type, Byte *pBuf, UInt16 iBufSize)
{
Iter iter, end = decoders.end();
if((iter = decoders.find(type)) != end)
{
return *iter->Decode(pBuf, iBufSize);
}
throw PacketDecoderNotFoundException(type);
}

The question is if UInt16 type can be known at compile time.. I guess it
cannot... but I tried to see how close I could get... And the solution
involves a function pointer array, instead of a case, but I do get rid of
the virtual function....

I have no idea how this will perform, so you will have to give it a go...
with a profiler...

Hope this will help you in any way ...

Jesper

enum encoder {
kSpecialDecoderOne=0,
kSpecialDecoderTwo
};
typedef short (*DecodePtr) (void*,short);

struct UnknownPackage {
};

template <encoder T>
struct Decoder
{
encoder T;
short Decode(void *pBuf, short iBufSize);
};

template <>
struct Decoder<kSpecialDecoderOne>
{
encoder kSpecialDecoderOne;
static short Decode(void *pBuf, short iBufSize)
{
std::cout << "Decoding message type 1"<<std::endl;
return 1;
}
};

template <>
struct Decoder<kSpecialDecoderTwo>
{
encoder kSpecialDecoderTwo;
static short Decode(void *pBuf, short iBufSize)
{
std::cout << "Decoding message type 2"<<std::endl;
return 1;
}
};

struct PacketHandler {
short Decode(encoder typeI, void *pBuf, short iBufSize)
{
static DecodePtr typeArray[]={ (&Decoder<kSpecialDecoderOne>::Decode) ,
&Decoder<kSpecialDecoderTwo>::Decode };
static unsigned long arraySize = sizeof(typeArray)/sizeof(DecodePtr);

//array boundscheck
if (typeI>=0 && typeI<arraySize)
return typeArray[typeI](pBuf,iBufSize);
throw UnknownPackage();
}
};

int main(int /*argc*/,char*[] /*argv*/)
{
PacketHandler packetHandler;
packetHandler.Decode(kSpecialDecoderOne,0,0);
packetHandler.Decode(kSpecialDecoderTwo,0,0);
return 0;
}
"Martin" <pe*******@hotmail.com> wrote in message
news:9b**************************@posting.google.c om...
Well I guess I should explain myself.

I have a "packet decoder" that uses the Strategy pattern.
There's a hash_map which maps packet types to PacketDecoders(which all
inherits from AbstractDecoder).

struct AbstractDecoder
{
virtual UInt16 Decode(Byte *pBuf, UInt16 iBufSize) = 0;
};
struct SpecialDecoderOne : public AbstractDecoder
{
virtual UInt16 Decode(Byte *pBuf, UInt16 iBufSize)
{
std::cout << "Decoding message type 1"<<std::endl;
return 1;
}
};

typedef stdext::hash_map<const
UInt16,AbstractDecoder*,std::equal_to<UInt16> > DecoderStrategy;
typedef DecoderStrategy::const_iterator Iter;

DecoderStrategy decoders;

//here we relay the decoding to the special packet decoder.
UInt16 PacketHandler::Decode(UInt16 type, Byte *pBuf, UInt16 iBufSize)
{
Iter iter, end = decoders.end();
if((iter = decoders.find(type)) != end)
{
return *iter->Decode(pBuf, iBufSize);
}
throw PacketDecoderNotFoundException(type);
}

I'd ultimately like to lose the virtual functions by using the inherit
from template parameter trick

template <class T>
class AbstractDecoder
{
public:
UInt16 Decode(Byte *pBuf, UInt16 iBufSize)
{
T *pT = static_cast<T*>(this);
return pT->DecodeImpl(pBuf, iBufSize);
}
protected:
UInt16 DecodeImpl(Byte *pBuf, UInt16 iBufSize)
{
std::cout <<"OOPS no DecodeImpl in subclass"<<std::endl;
}
};

struct SpecialDecoderOne : public AbstractDecoder<SpecialDecoderOne>
{
UInt16 DecodeImpl(Byte *pBuf, UInt16 iBufSize)
{
std::cout << "Decoding message type 1"<<std::endl;
return 1;
}
};

The reason to this is I want the decoder to be as efficient as
possible short
of doing a big switch(type) over all the different packets.

I will accept if it's not possible to achieve this in anyway though
:-)

edit: please overlook any missing "const" :-P

Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: SainTiss | last post by:
Hi, Is there an extra overhead in using virtual functions and templates? Or is is just the same overhead as with regular classes? Either way, if you'd want to avoid it, will you always end up...
4
by: Sat | last post by:
Hi, I have a simplified version of a problem that I am facing (hope I haven't oversimplified it). This code doesn't work now and I want to find how I can make it work. Can I call the derived...
25
by: Stijn Oude Brunink | last post by:
Hello, I have the following trade off to make: A base class with 2 virtual functions would be realy helpfull for the problem I'm working on. Still though the functions that my program will use...
6
by: RainBow | last post by:
Greetings!! I introduced the so-called "thin-template" pattern for controlling the code bloat caused due to template usage. However, one of the functions in the template happens to be virtual...
7
by: Vyacheslav Lanovets | last post by:
Hello, All! One of our target platforms has only 32 MB of virtual memory (Windows CE), so we decided to explicitly load some of our dlls. But the classes created inside such dlls are created...
4
by: pocmatos | last post by:
Hi all, I have an abstract class acting as interface to a given class of objects. And mostly everywhere around my program I'm passing things like: vector<int>, list<unsigned long>,...
11
by: Nindi73 | last post by:
A few days a ago I posted my code for a deep copy pointer which doesn't require the pointee object to have a virtual copy constructor. I need help with checking that it was exception safe and...
5
by: alind | last post by:
I m having a problem with templates. A per C++ std says i cant use override template virtual functions. in other words virtual functions cant be templates due to some vtable size issues. Now i want...
5
by: want.to.be.professer | last post by:
For OO design, I like using virtual member function.But considering efficiency, template is better. Look at this program, class Animal { public: virtual void Walk() = 0; }; class Dog
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
0
by: jack2019x | last post by:
hello, Is there code or static lib for hook swapchain present? I wanna hook dxgi swapchain present for dx11 and dx9.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.