472,971 Members | 1,965 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,971 software developers and data experts.

casting abstract classes

Dear gurus,

I have been reading about polymorphism and generally think that I get the idea. At least I've gotten some code to work. Now I'm trying to get a little fancier and can't seem to figure out the following dilemma.

I have an abstract class Base, and some Derived classes:

Expand|Select|Wrap|Line Numbers
  1. class Base {
  2. public:
  3.     void f1 () {
  4.               //....
  5.         }
  6.  
  7.       virtual void f2() = 0;
  8. };
  9.  
  10. class Derived1 {
  11. public:
  12.         Derived1(int p1, int p2) {
  13.               //...
  14.         }
  15.       void f2() {
  16.               //...
  17.         }
  18. };
  19.  
  20. class Derived2 {
  21. public:
  22.         Derived2(int p1, int p2) {
  23.               //...
  24.         }
  25.       void f2() {
  26.         //...
  27.         }
  28. };
  29.  
  30.  
Until recently, I was happy with just declaring a derived class and using it:

Expand|Select|Wrap|Line Numbers
  1. void someFunc(Base var);
  2.  
  3. int main(int argc, char *argv[]) {
  4.      Derived var(p1, p2);
  5.  
  6.      someFunc(var);
  7.      return 0;
  8. }
Now, what I really want is to be able to decide at runtime what class type to use. I can't pre-declare it either because I have pure virtual functions (e.g. f2) in my Base class. I tried making them non-pure (just empty) and then assigning like this:

Expand|Select|Wrap|Line Numbers
  1. void someFunc(Base var);
  2.  
  3. int main(int argc, char *argv[]) {
  4.      Base var;
  5.      if (arg[1] == 0) {
  6.            Derived1 v(p1, p2);
  7.            var = v;
  8.      } else {
  9.            Derived2 v(p1, p2);
  10.            var = v;
  11.      }
  12.  
  13.      someFunc(var);
  14.      return 0;
  15. }
It compiled fine, but the program clearly does not work right. So now I'm realizing that I'm missing some concepts here and need help.
Thanks in advance
Feb 17 '08 #1
9 6445
gpraghuram
1,275 Expert 1GB
Dear gurus,

I have been reading about polymorphism and generally think that I get the idea. At least I've gotten some code to work. Now I'm trying to get a little fancier and can't seem to figure out the following dilemma.

I have an abstract class Base, and some Derived classes:

Expand|Select|Wrap|Line Numbers
  1. class Base {
  2. public:
  3.     void f1 () {
  4.               //....
  5.         }
  6.  
  7.       virtual void f2() = 0;
  8. };
  9.  
  10. class Derived1 {
  11. public:
  12.         Derived1(int p1, int p2) {
  13.               //...
  14.         }
  15.       void f2() {
  16.               //...
  17.         }
  18. };
  19.  
  20. class Derived2 {
  21. public:
  22.         Derived2(int p1, int p2) {
  23.               //...
  24.         }
  25.       void f2() {
  26.         //...
  27.         }
  28. };
  29.  
  30.  
Until recently, I was happy with just declaring a derived class and using it:

Expand|Select|Wrap|Line Numbers
  1. void someFunc(Base var);
  2.  
  3. int main(int argc, char *argv[]) {
  4.      Derived var(p1, p2);
  5.  
  6.      someFunc(var);
  7.      return 0;
  8. }
Now, what I really want is to be able to decide at runtime what class type to use. I can't pre-declare it either because I have pure virtual functions (e.g. f2) in my Base class. I tried making them non-pure (just empty) and then assigning like this:

Expand|Select|Wrap|Line Numbers
  1. void someFunc(Base var);
  2.  
  3. int main(int argc, char *argv[]) {
  4.      Base var;
  5.      if (arg[1] == 0) {
  6.            Derived1 v(p1, p2);
  7.            var = v;
  8.      } else {
  9.            Derived2 v(p1, p2);
  10.            var = v;
  11.      }
  12.  
  13.      someFunc(var);
  14.      return 0;
  15. }
It compiled fine, but the program clearly does not work right. So now I'm realizing that I'm missing some concepts here and need help.
Thanks in advance
You are speaking about polymorphism and you haven't used virtual or inherited from base class.

Raghuram
Feb 17 '08 #2
weaknessforcats
9,208 Expert Mod 8TB
You are close.


What you do at runtime is create a Derived object.

Then assign the address of this object to a Base pointer.

Your example shows assignment to a Base object and this is incorrect. When you assign to a Base object, the Derived object is sliced so that the Derived part is cut off. Bad news. In C++ polymorphism only works when you use a Derived object through a Base* otr a Base&.

Next, since a Derived object is being used as a Base object, then it is important to call a Derived method instead of a Base method when this Derived object is used as a Base* or Base&. This is where the virtual function comes in.

Try to example again, only this time use a Base* to represent your Derived object.
Feb 17 '08 #3
You are speaking about polymorphism and you haven't used virtual or inherited from base class.

Raghuram
yes, sorry, I meant to write:

Expand|Select|Wrap|Line Numbers
  1. class Derived1 : public Base {
  2.  
  3. }
  4. class Derived2 : public Base {
  5.  
  6. }
Feb 17 '08 #4
You are close.


What you do at runtime is create a Derived object.

Then assign the address of this object to a Base pointer.

Your example shows assignment to a Base object and this is incorrect. When you assign to a Base object, the Derived object is sliced so that the Derived part is cut off. Bad news. In C++ polymorphism only works when you use a Derived object through a Base* otr a Base&.

Next, since a Derived object is being used as a Base object, then it is important to call a Derived method instead of a Base method when this Derived object is used as a Base* or Base&. This is where the virtual function comes in.

Try to example again, only this time use a Base* to represent your Derived object.
Thanks! The pointer did the trick (mostly). The following works as expected:
Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <iostream>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. class Base {
  9. public:
  10. //   string temp;
  11.   virtual void whoami() = 0;
  12. };
  13.  
  14. class Derived1 : public Base {
  15. public:
  16.   virtual void whoami() {
  17.     cout << "== Derived1 ==" << endl;
  18.   }    
  19. };
  20.  
  21. class Derived2 : public Base {
  22. public:
  23.   virtual void whoami() {
  24.     cout << "== Derived2 ==" << endl;
  25.   }
  26. };
  27.  
  28. int main(int argc, char *argv[]) {
  29.   int t = 0;
  30.   Base * var;
  31.  
  32.   if (t == 1) {
  33.     Derived1 v;
  34.     var = &v;
  35.     var->whoami();
  36.   } else if (t == 0) {
  37.     Derived2 v;
  38.     var = &v;
  39.     var->whoami();
  40.   }
  41.   var->whoami();
  42.  
  43.   return 0;
  44. }
The only problem I have left is if I uncomment the string temp declaration in line 10, The program crashes with the following message:

Expand|Select|Wrap|Line Numbers
  1. == Derived2 ==
  2. pure virtual method called
  3. terminate called without an active exception
  4. Abort
  5.  
I am working with a much bigger code base in reality and it took me a while to isolate the issue to that seemingly innocent declaration. I am starting to think that this is a compiler issue. Does anyone have any clues? I am using gcc version 4.1.2

Thanks.
Feb 18 '08 #5
weaknessforcats
9,208 Expert Mod 8TB
If t is not 0 or 1 you will call var->whoami() when it is still an uninitialized Base*.

Ka-Boom!
Feb 18 '08 #6
If t is not 0 or 1 you will call var->whoami() when it is still an uninitialized Base*.

Ka-Boom!
yes, I realize that. I'm omitting some safety checks to keep the example short. Clearly, t is initialized here, it goes Ka-Boom anyway, but only if I uncomment line 10.
Feb 18 '08 #7
weaknessforcats
9,208 Expert Mod 8TB
Well I uncommented line 10 (string temp), compiled and executed this using Visual Studio.NET 2005 and it did not Ka-Boom.

Is the code in your Post #5 the exact code that crashes??
Feb 19 '08 #8
Well I uncommented line 10 (string temp), compiled and executed this using Visual Studio.NET 2005 and it did not Ka-Boom.

Is the code in your Post #5 the exact code that crashes??
yes, it is. What is even more weird is that if I declare 'int temp' instead, it works fine. I finally got everything to work by declaring 'new Derived'. If someone can explain to me why this makes sense, that would be great, otherwise the thread can be considered closed. Here is the working code in case somebody else cares:

Expand|Select|Wrap|Line Numbers
  1. class Base {
  2.   string temp;
  3. public:
  4.   virtual void whoami() = 0;
  5. };
  6.  
  7. class Derived1 : public Base {
  8. public:
  9.   virtual void whoami() {
  10.     cout << "== Derived1 ==" << endl;
  11.   }    
  12. };
  13.  
  14. class Derived2 : public Base {
  15. public:
  16.   virtual void whoami() {
  17.     cout << "== Derived2 ==" << endl;
  18.   }
  19. };
  20.  
  21. int main(int argc, char *argv[]) {
  22.   int t = 0;
  23.   Base * var;
  24.  
  25.   if (t == 1) {
  26.     //Derived1 v;
  27.     //var = &v;
  28.     var = new Derived1;
  29.     var->whoami();
  30.   } else if (t == 0) {
  31.     //Derived2 v;
  32.     //var = &v;
  33.     var = new Derived2;
  34.     var->whoami();
  35.   }
  36.   var->whoami();
  37.  
  38.   return 0;
  39. }
  40.  
Feb 19 '08 #9
weaknessforcats
9,208 Expert Mod 8TB
Your crash is here:
Expand|Select|Wrap|Line Numbers
  1. if (t == 1) {
  2.     Derived1 v;
  3.     var = &v;
  4.     var->whoami();
  5.   } else if (t == 0) {
  6.     Derived2 v;
  7.     var = &v;                 <<<<<<<<<<<<<<<<<<<<<<<<<
  8.     var->whoami();
  9.   }
  10.   var->whoami();                   <<<<<<<<<<KA-BOOM!
  11.  
The Derived2 object goes out of scope at the end of the if statement. But you still use the object after it has gone out of scope.

This is the old: A function can never return an address or a reference to a local variable.
Feb 20 '08 #10

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

Similar topics

3
by: Kurt | last post by:
i just can't figure out why something im doing is not working correctly.... public interface IInterface { int someProperty { get; set; }
0
by: Kurt Lange | last post by:
no... the array is created dynamically. and no... that defeats the purpose of what im trying todo.. encapsulate all initializing of variables in base class... derive from it... by deriving...
2
by: philippe sillon | last post by:
Hi, I have a problem to implemente the strategy pattern. the problem come from that a method take different arguments type (object in interface and String / Int in implemented class). When...
2
by: Lars-Erik Aabech | last post by:
Hi! I've got a small challenge with my class library. I've got an abstract base class with some protected fields. It has two derived classes, and it should be possible to cast these classes to...
12
by: Steve Teeples | last post by:
Can someone tell me the correct method of casting and object at run time. Here is a sample of what I'm trying to do. classA acts as a base for classes that execute code in classes derived from...
0
by: Greg Conely via .NET 247 | last post by:
I am creating a application that will be using plugins. I am doing this so that when I want to let this application work with another type of dbase system, I only have to write\install one plugin,...
8
by: Michael | last post by:
Hi, I think my problem deals with class casting and inheritance. I want to deal with various Audio Formats, reading into memory for modification, working with it (done by different classes),...
5
by: anders.forsgren | last post by:
This is a common problem with generics, but I hope someone has found the best way of solving it. I have these classes: "Fruit" which is a baseclass, and "Apple" which is derived. Further I have...
10
by: Brett Romero | last post by:
Say I have a class inheriting some base class: BaseClass { void Foo() { Update(); } }
17
by: Tem | last post by:
I have classes A,B,C,D,E,F that implement InterfaceBase. Whats the best way to down cast obj to the correct type? Is there a more elegant way to do this than? Public Void...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
3
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.