Paul
Paul

Reputation: 101

Changing between user defined classes at runtime in C++

I have two classes with one extending the other. They both have a method called doSomething() that perform something different. I want to be able to have one pointer that I can switch from class A to class B and have the rest of the code run the same because they each have the same method name. Is this possible and is this the correct way to do it? Also, I'm pretty new to C++ so it could be just a problem with that.

class A {
    void doSomething()
    {
        // does something
    }
};

class B: public A {
    void doSomething()
    {
        //does something else
    }
};


main()
{
    A *ptr = new A;
    B *bptr = new B;

    // a giant loop

    ptr->doSomething();


    if(condition) 
    {
        ptr = bptr;
    }
}

Upvotes: 1

Views: 235

Answers (2)

Chad
Chad

Reputation: 19032

Two ways I can think of to accomplish this.

Your way is fine (with some small changes) if you already have polymorphic types). (If B is-an A, logically)

class A
{
public:
    virtual void f() { /* something */ };
};

class B : public A
{
public:
   virtual void f() { /* something else */ };
};

int main()
{
   A a;
   B b;
   A* c = 0;

   // based on your condition
   c = &a;
   c->f();
   c = &b;
   c->f();

   return 0;
}

But what if your types aren't really that closely related? Using inheritance implies a very rigid (is-a, in this case) relationship between your classes. Is a B really an A?

Here's a way to accomplish this for classes that have the same named function, but aren't really of similar types.

template <class T>
void do_f(T& obj)
{
   obj.f();
}

class D
{
public:
   void f() { /* something */ }
};

class E
{
public:
   void f() { /* something else entirely */ }
};

int main()
{
   // note, D and E have no relation
   D d;
   E e;

   // based on your condition
   do_f(d);
   do_f(e);
}

Upvotes: 5

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726559

What you are trying to achieve is called polymorphism. In C++, you will need to define a common (possibly abstract) base class C for A and B, make doSomething a virtual function, override it in both A and B, and make pointers of type C*. Here is a good introductory article on the topic.

Upvotes: 2

Related Questions