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?
perlperlAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

perlperlAuthor Commented:
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) {
0
Kyle AbrahamsSenior .Net DeveloperCommented:
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/
0
Kyle AbrahamsSenior .Net DeveloperCommented:
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
0
Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

perlperlAuthor Commented:
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
0
ZoppoCommented:
Hi perlperl,

the problem is your base class doesn't declare any virtual functions. In description of typeid I found this:
The expression must point to a polymorphic type (a class with virtual functions).
You example works for me as soon as I i.e. declare the base class destructor as virtual (this always is a good idea when deriving classes).

Hope that helps,

ZOPPO
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ZoppoCommented:
hehe - you accidentally solved it by adding these two virtual functions ... :o)
0
perlperlAuthor Commented:
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
0
ZoppoCommented:
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
0
perlperlAuthor Commented:
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
0
perlperlAuthor Commented:
You are genius Mr ZOPPO  hats off :)
0
ZoppoCommented:
:)

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.
0
perlperlAuthor Commented:
I knew the use case for virtual destructor ;) but I never knew that typeid also needs at least one virtual function in base class ;)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.