Link to home
Start Free TrialLog in
Avatar of perlperl
perlperl

asked on

polymorphism and passing derived class object as reference to base class

class Base {
   public:
     Base() { printf (" base Const ... \n"); }
     ~Base() { printf (" base Dest ... \n"); }
};

class Derived : public Base {
   public:
     Derived(): d(100) { printf (" Derived Const ... \n"); }
     void disp() const { printf ("Der Display .................. \n"); }
     ~Derived() { printf (" Derived Dest ... \n"); }
     int d;

};

void func_2 (const Base& der);
void merge(const Derived& der) {
   printf("Val = %d\n", der.d);
}

int main(int argc, char *argv[]){
   std::auto_ptr<Derived> der;
   der.reset(new Derived());
   printf ("DONT Tranfer auto_ptr to func. just pass the reference \n");
   func_2(*der);
   printf ("Back to main \n");

}

void func_1 (const Derived& der) {
   printf ("Inside Derived_func() .... \n");
}

void func_2 (const Base& b) {
    printf("Inside Base_func \n");
    if (typeid(b) == typeid(Derived))
      printf ("I am DERVIED \n");
    const Derived& der = static_cast<const Derived&> (b);
    merge(der);
}

Open in new window


The output I get is:
 base Const ...
 Derived Const ...
DONT Tranfer auto_ptr to func. just pass the reference
Inside Base_func
Val = 100
Back to main
 Derived Dest ...
 base Dest ...


Why is it not printing
I am DERVIED   inside function func_2()
Am I incorrectly using the typedid?
Avatar of perlperl
perlperl

ASKER

Earlier
void func_2 (const Base& b) {

was
void func_2 (const Derived& b) {


but I had to change it take Base& as now this function can take more than one Derived class and I just want to re-use this fucntion instead of creating new one something like
void func_2 (const Dervied_2& b) {
Avatar of Kyle Abrahams, PMP
the easiest way to check would be to printf for each typeid.

But thinking about it logically theres no way the types should be the same, one is derived from the other sure, but they're two totally seperate things.

http://stackoverflow.com/questions/1986418/typeid-and-typeof-in-c


if you wanted to see the actual classes:
http://www.cplusplus.com/reference/typeinfo/type_info/name/
In regrards to your second comment I would recommend templating it out or adding a "type" to the base class this way you know which type you're dealing with.

Something similar to:
http://stackoverflow.com/questions/2355195/check-for-derived-type-c
This worked for me.

class Base {
   public:
     Base() { printf (" base Const ... \n"); }
     ~Base() { printf (" base Dest ... \n"); }
     virtual bool is_der_1() const = 0;
     virtual bool is_der_2() const = 0;
};

class Derived : public Base {
   public:
     Derived() { printf (" Derived Const ... \n"); }
     ~Derived() { printf (" Derived Dest ... \n"); }
     virtual bool is_der_1() const { return true; }
     virtual bool is_der_2() const { return false; }

};

void func_2 (const Base& der);
void merge(const Derived& der) {
   printf("Merge = \n");
}

int main(int argc, char *argv[]){
   std::auto_ptr<Derived> der;
   der.reset(new Derived());
   printf ("DONT Tranfer auto_ptr to func. just pass the reference \n");
   func_2(*der);
   printf ("Back to main \n");

}

void func_2 (const Base& b) {
    printf("Inside Base_func \n");
    if (b.is_der_1())
      printf ("I am DERVIED \n");

    const Derived& der = static_cast<const Derived&> (b);
    merge(der);
}

Open in new window


I don't know why the "typeid" didn't work in my original post
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
hehe - you accidentally solved it by adding these two virtual functions ... :o)
Yup, I removed those two new virtual functions and just made base class destructor virtual and it worked.

That is quite interesting. puzzles me why
The problem AFAIK is that some RTTI-related functions only works if base class has at least one virtual function because functions like i.e. typeid or dynamic_cast use the v-table of the instances to determine the real type, but for classes witout virtual functions no v-tables exist so these functions return different results.

ZOPPO
BTW, my intentions of adding virtual functions was different ;) I was just finding a way to find out whether object is from which derived class ;)

You gave me the exact reasoning on it usage ;)

sometimes c++ is crazy language
You are genius Mr ZOPPO  hats off :)
:)

BTW, as I mentioned before it's highly recommended to implement base class destructor as virtual because otherwise the derived classes destructor wouldn't be called.
I knew the use case for virtual destructor ;) but I never knew that typeid also needs at least one virtual function in base class ;)