user1495421
user1495421

Reputation: 69

How to make a base class object call a derived class non virtual function?

I have a base class with pure virtual functions and I have a derived class with definitions for the base class virtual functions as well as its own functions.

Now I have pointed the base class object to derive class, like:

Base *bc =new Child();

I want to call the child class method (not defined or declared in the parent) using this object.

But I am getting compiler error memeberFunction not define in Base class.

The code is as:

class Base
{
public:
  virtual void method1() = 0;
};

class child : public Base
{
public:
  virtual void method1() {}
  void Method2() { /* some implementation */ }
};

How can I achieve this?

bc->Method2();

Upvotes: 1

Views: 752

Answers (5)

SylvainL
SylvainL

Reputation: 3938

One of the principle of OOP is the ability to see a group of different objects trough a common set of functions. For solving your problem, you could use either a dynamic or a static cast but by doing this way, you are throwing out of the window one of the most useful aspect of OOP.

If you start doing right and left a lot of casts for your objects, then what's the purpose of having an hierarchy of inheritance (polymorphism) in the first place?

In general, OOP will work well when you set up a lot of (pure) virtual functions at the base of your hierarchy; even if some or many of these functions won't be useful for some of the subclasses.

Upvotes: 1

Tannin
Tannin

Reputation: 508

The correct way to do things really depends on what you're trying to express. Assume your class hierarchy is: class Animal

class Kangoroo is an animal and it can jump

now with your Animal pointer you only know that it is an animal. You can't make it jump, for all you know the pointer could be pointing to an Elephant.

Your three options: a) Don't make animal jump at all (use a kangoroo pointer instead) b) use dynamic_cast. This way you can express: If it is a kangoroo, make it jump, otherwise don't c) add jump() to the base class (animal) and have Elephant::jump throw an exception or do nothing.

The b solution becomes very complicated if you also want other animals to jump. Also many C++ programmers dislike dynamic_cast.

Upvotes: 0

Mats Petersson
Mats Petersson

Reputation: 129524

The CORRECT way to do this is to implement a Method2 on the baseclass. There is no ifs, buts or alternatives if you want to do it the right way. The wrong way is to use dynamic_cast, which will WORK, but it's still not the right thing to do.

If you absolutely can't change the baseclass, then you have to ask yourself why it wasn't part of the baseclass in the first place. Note that if it's something the class is expected to be able to do in a child, but you can't do in the baseclass for some reason, then the right thing is to either implement it as a pure virtual, or have an implementation that does some suitable "This is not the member function you are looking for" type operation.

Upvotes: 0

cooky451
cooky451

Reputation: 3510

The fact that you want to do this alone points to a bad design choice. The use of dynamic_cast points to a bad design choice as well in most cases. Also note that dynamic_cast is very slow, much slower than calling a virtual function. You can, by the way, use static_cast to cast down the derivation tree. This is of course as well extremely rare (CRTP would be an example). I also wonder, at this point: How do you know that the object is a "child" and not some other Base-Derived object? And if you do really do know that, why don't you work with a child* instead of a Base* in the first place? (Btw take a look at smart pointers, e.g. unique_ptr.)

Upvotes: 2

Maciej
Maciej

Reputation: 3723

You should cast (using dynamic_cast) bc to Child *, and then call Method2().

Upvotes: 0

Related Questions