Question

I have the following simple class

class base
{
public:
  int x;
  base &set(int y)
    {
      x = y;
      return *this;
    }
};

and want to create a new one with added functionality, say to print the value x. So I do:

class derived : public base
{
public:
  void print()
    {
      cout << x << endl;
    }
};

Now in the main program I want to do something like

D.set(2).print();

for which however the compiler complains that class base has no member named 'print'.

If I try to use covariant return types and write the two classes as

class base
{
public:
  int x;
  virtual base &set(int y)
    {
      x = y;
      return *this;
    }
};

class derived : public base
{
public:
  derived &set(int y)
    {
      x = y;
      return *this;
    }
  void print()
    {
      cout << x << endl;
    }
};

then the statement works just fine, but I was forced to rewrite the exact same function body for 'set' in both classes, even though the only thing that changes is the return type.

If later on I need to change the functionality of base::set then I will have to go through all the derived classes to change the 'set' function... are there any ways to avoid that? Thanks in advance!

Was it helpful?

Solution

C++ work as you say, and you say in your base class set return base&, so that is what C++ do. But in order to solve this you have many ways.

First you are not forced to make a function virtual to override it in a derived class (note that virtual call are slightly slower than normal calls).

Second you can refer to base class implementation as base::set so the code will be as follow:

class base {
    ...
    base& set( int x ) {...}
};
class derived : public base {
    derived& set( int x ) {
        return static_cast<derived&>( base::set(x) );
    }
};

OTHER TIPS

Depending on your circumstances, you might be able to use the CRTP:

template <class D>
class base {
    D& set(int x) {
        …;
        return *static_cast<D*>(this);
    }
};

class derived : base<derived> { … };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top