473,395 Members | 2,446 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Get Derived (templated) from Base Pointer?

I have a templated class, CDerived:

template <typename TValue, typename TDraw, typename TEdit ...>
class CDerived : public CBase
{
TValue m_Value
public:

TValue& GetValue() const
{
return m_Value;
}

void Draw()
{
TDraw::Draw(this);
}

void Edit()
{
TEdit::Edit(this);
}
};

It is designed as a generic class that is constructed by passing in various "policy classes" as template arguments (different composite types are created using typedefs). I need to store pointers to CDerived objects in a container.

In order to accomplish this, I've created a non-templated CBase from which CDerived derives, in order to store the CBase* pointers in the container, since the container cannot store CDerived* pointers since they are not all of the same type due to the template arguments of CDerived.

I have a few pure virtual functions in CBase that are overriden in CDerived. In it's implementation, CDervied just makes calls to the policy classes static methods, passing in it's this pointer. This works fine as long as the virtual functions in CBase and CDerived have the same signatures (parameter types and return type).

My problem occurs in that one of the template members passed into CDerived is a Value that it holds. Value can be any arbitrary object, not necessarily a POD type. The only rule is that the TDraw, TEdit, etc. must be able to handle the TValue type.

I need to be able to call GetValue() in the container, but since the container only holds CBase* objects, it can't call GetValue(). GetValue() cannot be a virtual function because the return type is variable depending on the TValue template argument in CDerived. It cannot be a templated virtual function because templated virtual functions are not allowed (MSVC). It cannot be a simple template function because CBase does not know the return type and CBase cannot be templated if stored in a homogenous container.

I've experimented with many different approaches, including handle classes, visitor objects, chameleon objects, etc.; none of which work.

None of these work because in all cases you need to know the target types beforehand, and I don't know all of the target types because CDerived is templated with exponential combinations of template types.

It's interesting that sizeof() and typeid() obviously are able to figure out the type of the derived class from a base class pointer, but there appears to be no support in the language for figuring this out.

What I need to do is either:
1) Given a CBase* pointer, in a container that does not know beforehand what specific CDerived is pointed to, get a CDerived* pointer and be able to call methods on that pointer.
2) Have a way to store CDerived* objects on a container and get the properly-typed pointer out in the container and call methods on it (without the container knowing the pointer's type beforehand, just that the pointed-to object does implement the methods, such as GetValue() that will be called by the container).

I have a feeling that there must be some way to do this, though I have not seen anything that indicates it is possible.

Does anyone have any ideas?

~Mike
Dec 6 '07 #1
2 2901
weaknessforcats
9,208 Expert Mod 8TB
Not true:
It cannot be a templated virtual function because templated virtual functions are not allowed (MSVC).
I converted your snippet to templates then compiled and linked it using Visual Studioi.NET 2005:
Expand|Select|Wrap|Line Numbers
  1. template <typename TValue, typename TDraw, typename TEdit >
  2. class CBase
  3. {
  4.     public:
  5.         virtual TValue GetValue() const;
  6. };
  7.  
  8. template <typename TValue, typename TDraw, typename TEdit >
  9. class CDerived : public CBase<TValue,TDraw,TEdit>
  10. {
  11. TValue m_Value;
  12. public:
  13.  
  14. virtual TValue& GetValue() const
  15. {
  16. return m_Value;
  17. }
  18.  
  19. void Draw()
  20. {
  21. TDraw::Draw(this);
  22. }
  23.  
  24. void Edit()
  25. {
  26. TEdit::Edit(this);
  27. }
  28. };
  29. int main()
  30. {
  31.  
  32. }
  33.  
I will post again later.
Dec 7 '07 #2
weaknessforcats
9,208 Expert Mod 8TB
If your container has CBase* for the data, then all methods you can call have to be handled by the base class.

That means,

a) your virtual functions should be private so when a public base method is called, it can all the private method to don the work. The private method is overriden by the derrived class so it ti actually the derived method that is executed. The separates the interface from the implementation. Check out the design pattern called Template Method

b) all virtual methods of the derived class should be private

c) if a derived class has methods beyond the base class, then you use a visitor.

d) your CBase that this not a template won't work when GetValue() is a termplate method due to the different return types. Thhis forces CBase to be a template as well.
Dec 8 '07 #3

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: tirath | last post by:
Hi all, I have a templated class that derives from a non-templated abstract class. How do I then cast a base class pointer to a <templated> derived class pointer in a generalised fashion? ...
1
by: Art | last post by:
This is partially an academic question, but I'm trying to understand templates better. I have a base class that uses template parameters to define the behavior of its class. I want to subclass this...
1
by: FP | last post by:
I have a function that returns a base class pointer as in: baseClass<T>* FunctionA( ); As you can see the baseClass is templated. FunctionA is found in a third templated class. What I'm...
2
by: Siemel Naran | last post by:
This code fails compile std::auto_ptr<Base> f() { std::auto_ptr<Derived> out(new Derived()); return out; } There is ambiguity between a templated constructor and templated operator...
25
by: Jack | last post by:
Hi, Is there a general solution for the following problem: I have an array of instances of class B. Class B is publicly derived from class A. Then I have a class named Buffer that generally...
4
by: nozyrev | last post by:
Hi, I apologize in advance if this is a very dumb question. I've been struggling with this problem for some time: I have an abstract base class called Base and n derived classes D1, D2, ....Dn. I...
12
by: bgold | last post by:
Hey. I have a base class (SPRITE), and using this base class I have derived a large number of derived classes (PERSON, BULLET, MISSILE, etc.). Now, at a certain point in my program, I have a pair...
10
by: Dom Jackson | last post by:
I have a program which crashes when: 1 - I use static_cast to turn a base type pointer into a pointer to a derived type 2 - I use this new pointer to call a function in an object of the...
9
by: Steven Powers | last post by:
Imagine the following setup class Parent { virtual void doStuff(); } class Child : public Parent { virtual void doStuff(); }
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.