Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call derived class method from base class pointer?

I have a class structure similar to the following

class A
{
public:
    A(void);
    ~A(void);

    void DoSomething(int i)
    {
        std::cout << "Hello A" << i << std::endl;
    }
};

class B : public A
{
public:
    B(void);
    ~B(void);

    void DoSomething(int i)
    {
        std::cout << "Hello B" << i << std::endl;
    }
};

class Ad : public A
{
public:
    Ad(void);
    ~Ad(void);
};

class Bd : public B
{
public: 
    Bd(void);   
    ~Bd(void);
};

I want to store instances of the derived classes in a container (standard map) as a collection of A*, then iterate through the container and call methods for each instance.

#include "A.h"
#include "B.h"
#include "Ad.h"
#include "Bd.h"
#include <map>
int main(int argc, char** argv)
{
    std::map<int,A*> objectmap;
    objectmap[1] = new Ad();
    objectmap[2] = new Bd();

    for (std::map<int,A*>::iterator itrobject = objectmap.begin();
         itrobject!=objectmap.end(); itrobject++)
    {
        itrobject->second->DoSomething(1);
    }
    return 0;
}

The above code produces the following output.

Hello A1
Hello A1

Where I was expecting

Hello A1
Hello B1

because I was expecting DoSomething in B to hide DoSomething in A, and because I am storing A pointers, I would expect no object slicing (and looking at the object pointer in the debugger shows that the object has not been sliced).

I have tried down casting and dynamic casting the pointer to B, but it slices away the data members of Bd.

Is there any way to call B::DoSomething without casting the pointer to Bd? And if not, if I have many derived classes of B (e.g. Bda, Bdb, Bdc etc), is there some way to use RTTI to know which derived class to cast it to?

like image 844
Ian Thompson Avatar asked Sep 19 '13 02:09

Ian Thompson


People also ask

Can a base class pointer call methods in the derived class?

When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

Can you convert a pointer from a derived class to its base class?

[19.4] Is it OK to convert a pointer from a derived class to its base class? Yes.

Can base class access methods of derived class?

base (C# Reference)The base keyword is used to access members of the base class from within a derived class: Call a method on the base class that has been overridden by another method. Specify which base-class constructor should be called when creating instances of the derived class.

How do you call a derived class from base class?

You could do something like this: class Base { public: Base() {} virtual ~Base() {} virtual void start() { startInternal(); } virtual void stop() { stopInternal(); } void doSomething() { startInternal(); // ... stopInternal(); } private: void startInternal() { // ... }


1 Answers

You need to make DoSomething() a virtual function in both classes to get the polymorphic behavior you're after:

virtual void DoSomething(int i) { ...

You don't need to implement virtual functions in every sub class, as shown in the following example:

#include <iostream>

class A {
    public:
        virtual void print_me(void) {
            std::cout << "I'm A" << std::endl;
        }

        virtual ~A() {}
};

class B : public A {
    public:
        virtual void print_me(void) {
            std::cout << "I'm B" << std::endl;
        }
};

class C : public A {
};

int main() {

    A a;
    B b;
    C c;

    A* p = &a;
    p->print_me();

    p = &b;
    p->print_me();

    p = &c;
    p->print_me();

    return 0;
}

Output:

I'm A
I'm B
I'm A

like image 113
Crowman Avatar answered Oct 18 '22 02:10

Crowman