473,386 Members | 1,753 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,386 software developers and data experts.

template inheritance

how can I get this upcasting to work:

Expand|Select|Wrap|Line Numbers
  1. template <class T>
  2. class BP : public T
  3. {}
  4. ;
  5. class DD : public class ST
  6. {}
  7. ;
  8. class ST
  9. {};
  10.  
  11. int main(int argc, char** argv)
  12. {
  13. shared_ptr<BP<ST> > spST;
  14. shared_ptr<BP<DD> > spDD(new BP<DD>());
  15. spST = boost::dynamic_pointer_cast<BP<ST> >(spDD); <-----------this line throws assertion px!=0 failed
  16. }
  17.  
is it something acheivable? i have just posted the design otherwise classes contains all the constructor, members etc.
Feb 28 '10 #1
9 1419
weaknessforcats
9,208 Expert Mod 8TB
class DD : public class ST
{}
;
class ST
{};
This violates a prome rule of inheritance: Never derive from concrete classes.
(See Scott Meyer More Effective C++ pp 258-270).

You need DD to derive from an ABC aand ST to derive from the same ABC.

That way you create a DD or an ST but use it as an ABC*.

In your example you create a DD and the address of this object cannot ever be a pointer to an ST becuse it is not an ST.

Remember, when you cast in C++ is because a) you care calling some relic function with a void* or somesuch or b) your C++ design is screwed up.
Mar 2 '10 #2
it's not casting from DD to ST which is a problem as that works. ST contains virtual methods. It's a casting from BP<DD> to BP<ST> which throws runtime exception.
Mar 3 '10 #3
weaknessforcats
9,208 Expert Mod 8TB
It's probably that the dynamic_cast makes a run-time check to verify that the object at the address you are casting from is, in fact, an object of the type you are casting to AND that the type you are casting from and casting to are in the same inheritance hierarchy.

What you have are BP objects and BP is not part of an inheritance hierarchy. Instead, these are handle objects that manage DD and ST objects. I expcect you will need an operator DD and an operator ST to support your cast. And then, you won't use a dynamic_cast but use a normal cast instead.

It still begs the question why you are doing this. Problems like this are usually handled by creating a Factory class that returns the adress of the correct type of object. The Factory object is created inside a Create function that returns the adress returned by the Factory. This is a common design pattern.
Mar 3 '10 #4
Expand|Select|Wrap|Line Numbers
  1. if ((*pmapVarNameAndValues)["type"] == "stddeviation")
  2.      {
  3.          shared_ptr<BP<StdDeviations> > pBP(new BP<StdDeviations>());
  4.          SHlpr::ConfigureStdDeviationsFromVariables(boost::dynamic_pointer_cast<StdDeviations>(pBP), *pmapVarNameAndValues);
  5.          pBP->m_itStartTime = iStartTimeOffset;
  6.          for(int i = 0; i < iRows - 1; i++)
  7.          {
  8.              for(int j = 0; j < 6; j++) dpocv[j] = npyary[i][j];
  9.              pBP->OnUpdate(dpocv);
  10.          }
  11.         pBP->m_bEnabled = false;
  12.          for(int j = 0; j < 6; j++) dpocv[j] = npyary[iRows - 1][j];
  13.          pBP->OnUpdate(dpocv);
  14.          pBP->Log(vctLog);
  15.  
  16.      }
  17.      else if ((*pmapVarNameAndValues)["type"] == "stddeviationrev")
  18.      {
  19.          shared_ptr<BP<StdDeviationsRev> > pBP(new BP<StdDeviationsRev>());
  20.          SHlpr::ConfigureStdDeviationsFromVariables(boost::dynamic_pointer_cast<StdDeviations>(pBP), *pmapVarNameAndValues);
  21.          pBP->m_itStartTime = iStartTimeOffset;
  22.          for(int i = 0; i < iRows - 1; i++)
  23.          {
  24.              for(int j = 0; j < 6; j++) dpocv[j] = npyary[i][j];
  25.              pBP->OnUpdate(dpocv);
  26.          }
  27.          pBP->m_bEnabled = false;
  28.          for(int j = 0; j < 6; j++) dpocv[j] = npyary[iRows - 1][j];
  29.          pBP->OnUpdate(dpocv);
  30.          pBP->Log(vctLog);
  31.  
  32.      }
  33.      else if ((*pmapVarNameAndValues)["type"] == "smoregression")
  34.      {
  35.          shared_ptr<BP<SmoRegression> > pBP(new BP<SmoRegression>());
  36.          SHlpr::ConfigureSmoRegressionFromVariables(boost::dynamic_pointer_cast<SmoRegression>(pBP), *pmapVarNameAndValues);
  37.          pBP->m_itStartTime = iStartTimeOffset;
  38.          for(int i = 0; i < iRows - 1; i++)
  39.          {
  40.              for(int j = 0; j < 6; j++) dpocv[j] = npyary[i][j];
  41.              pBP->OnUpdate(dpocv);
  42.          }
  43.          pBP->m_bEnabled = false;
  44.          for(int j = 0; j < 6; j++) dpocv[j] = npyary[iRows - 1][j];
  45.          pBP->OnUpdate(dpocv);
  46.          pBP->Log(vctLog);
  47.  
  48.      }
  49.      else if ((*pmapVarNameAndValues)["type"] == "detrendeddev")
  50.      {
  51.          shared_ptr<BP<DetrendedDev> > pBP(new BP<DetrendedDev>());
  52.          SHlpr::ConfigureDetrendedDevFromVariables(boost::dynamic_pointer_cast<DetrendedDev>(pBP), *pmapVarNameAndValues);
  53.          pBP->m_itStartTime = iStartTimeOffset;
  54.          for(int i = 0; i < iRows - 1; i++)
  55.          {
  56.              for(int j = 0; j < 6; j++) dpocv[j] = npyary[i][j];
  57.              pBP->OnUpdate(dpocv);
  58.          }
  59.          pBP->m_bEnabled = false;
  60.          for(int j = 0; j < 6; j++) dpocv[j] = npyary[iRows - 1][j];
  61.          pBP->OnUpdate(dpocv);
  62.          pBP->Log(vctLog);
  63.  
  64.  }
  65.  
I just want to generalize code below instead of calling it in every else if. All the template argument class to BP are derived from ST. OnUpdate is a vistual method. m_bEnabled is a memeber of ST. So this should work just need to figure out the way to cast BP<DerivedClass> to BP<ST>
for(int i = 0; i < iRows - 1; i++)
99 {
100 for(int j = 0; j < 6; j++) dpocv[j] = npyary[i][j];
101 pBP->OnUpdate(dpocv);
102 }
103 pBP->m_bEnabled = false;
105 for(int j = 0; j < 6; j++) dpocv[j] = npyary[iRows - 1][j];
106 pBP->OnUpdate(dpocv);
107 pBP->Log(vctLog);
Mar 3 '10 #5
weaknessforcats
9,208 Expert Mod 8TB
I am still not with you.

DD is your base class. ST is your derived class.

You create ST objects and use them through DD pointers. There is no cast. and ST IS-A DD.

DD* ptr = new ST;

Your shared_ptr would be managing a DD*.

There will be no ST pointers in your code.
Mar 3 '10 #6
DD is derived class and ST is base class. that all works fine. The issue is with BP which derives from template class argument.

So instead of creating
BP1 from DD1
BP2 from DD2
BP3 from DD3
i have created
template<class T>
BP : public <T>

DD1, DD2, DD3 and so on all derives from ST
so I just want to cast BP<DD1>, BP<DD2> so on to BP<ST>
Mar 3 '10 #7
Banfa
9,065 Expert Mod 8TB
You have not understood your own inheritance tree. You should draw it out, something that is normally worth while on any progrect if you have actually created your inheritance tree during the design stage before you started programming. If you did you would find it looked something like

Expand|Select|Wrap|Line Numbers
  1.                    ST
  2.                     |
  3.   ---------------------------------------
  4.   |           |            |            |
  5. BP<ST>       DD1          DD2          DD3
  6.               |            |            |
  7.            BP<DD1>      BP<DD2>      BP<DD3>
  8.  
From this it is easy to see that you can cast BP<DD1> to BP<ST> because they are on different branches of the inheritance tree.

A BP<DD1> is a DD1 and it is an ST but it is not a BP<ST>.
Mar 3 '10 #8
yes that's what causing issues. is there any way I can execute ST virtual functions on BP<DD> which i doubt. any design pattern recommend which best fits this scenario. I am willing to make design changes unless they are drastic.

Thanks for you time I really appreciate that.
Mar 3 '10 #9
weaknessforcats
9,208 Expert Mod 8TB
This is looking like you need a Handle. Read this: http://bytes.com/topic/c/insights/65...-smart-pointer

There still should not be a need for a cast:

Expand|Select|Wrap|Line Numbers
  1. class ST
  2. {
  3. public:
  4.     virtual void Hello()  {cout << "Hello" << endl;}
  5.  
  6. };
  7. class DD : public ST
  8. {
  9.  
  10. };
  11.  
  12.  
  13. class BP
  14. {
  15.      ST* theObject;
  16. public: 
  17.     BP(ST* obj) : theObject(obj) {};
  18.     ST* operator->() {return theObject;}
  19. };
  20.  
  21. int main()
  22. {
  23.     ST* obj = new DD;
  24.     BP handle(obj);
  25.     handle->Hello();
  26.  
  27. }
Here BP is a handle object. The insight article covers this in detail.
Mar 4 '10 #10

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

Similar topics

3
by: Gandu | last post by:
Could some C++ guru please help me? I have a very odd problem with respect templates and inheritance. I have templatized List class, from which I am inheriting to create a Stack class. All works...
13
by: Walt Karas | last post by:
The following gives an error in the declaration of the member function x() of the class template Tpl, compiliing with a recent version of GCC under Solaris: class A { }; class B { }; ...
3
by: Thomas Matthews | last post by:
Hi, I would like to apply inheritance to a template parameter, but my design fails to compile: cannot initialize one template class with child child parameterized class. I'll explain... ...
2
by: Tony Johansson | last post by:
Hello Experts To derive a concrete class from a template class in invalid. Why?? So you should not be able have something like this class Derived : public Base<int, 100> It's valid to derive...
1
by: Tony Johansson | last post by:
Hello Experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don't understand completely. Im I right if I say the...
5
by: Tony Johansson | last post by:
Hello experts! I have two class template below with names Array and CheckedArray. The class template CheckedArray is derived from the class template Array which is the base class This program...
13
by: jois.de.vivre | last post by:
Hi All, I'm trying to write a wrapper class for std::vector to extend some of its functionality. The problem I'm getting into is returning an iterator type from a member function. Here is the...
2
by: Thomas Kowalski | last post by:
Hi, I would like to write a template class Polygon<VertexTypthere vertex typ can be eigther a pointer or a value typ. It has an attribute: std::vector<VertexTypvertices; And a methode:...
9
by: stephen.diverdi | last post by:
Can anyone lend a hand on getting this particular template specialization working? I've been trying to compile with g++ 4.1 and VS 2005. ...
32
by: Stephen Horne | last post by:
I've been using Visual C++ 2003 for some time, and recently started working on making my code compile in GCC and MinGW. I hit on lots of unexpected problems which boil down to the same template...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...

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.