Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override number of parameters of pure virtual functions

I have implemented the following interface:

template <typename T>
class Variable
{
public:
  Variable (T v) : m_value (v) {}
  virtual void Callback () = 0;
private:
  T m_value;
};

A proper derived class would be defined like this:

class Derived : public Variable<int>
{
public:
  Derived (int v) : Variable<int> (v) {}
  void Callback () {}
};

However, I would like to derive classes where Callback accepts different parameters (eg: void Callback (int a, int b)). Is there a way to do it?

like image 670
Jir Avatar asked May 27 '10 08:05

Jir


People also ask

Can we override pure virtual function?

Yes !! It improves code clarity: override keyword prevents ambiguity and convey it's meaning of overriding its base class method.

What does it mean to override a pure virtual function?

A pure virtual function is a function that must be overridden in a derived class and need not be defined. A virtual function is declared to be “pure” using the curious =0 syntax.

Can a pure virtual function have parameters?

Yes, C++ virtual functions can have default parameters.

Do I need to override virtual functions?

It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used. A class may have virtual destructor but it cannot have a virtual constructor.


4 Answers

This is a problem I ran in a number of times.

This is impossible, and for good reasons, but there are ways to achieve essentially the same thing. Personally, I now use:

struct Base {   virtual void execute() = 0;   virtual ~Base {} };  class Derived: public Base { public:   Derived(int a, int b): mA(a), mB(b), mR(0) {}    int getResult() const { return mR; }    virtual void execute() { mR = mA + mB; }  private:   int mA, mB, mR; }; 

In action:

int main(int argc, char* argv[]) {   std::unique_ptr<Base> derived(new Derived(1,2));   derived->execute();   return 0; } // main 
like image 169
Matthieu M. Avatar answered Sep 21 '22 01:09

Matthieu M.


Even if such a thing were possible, it no longer makes much sense to have it as a virtual function, as the derived instantiations couldn't be called polymorphically via a pointer to the base class.

like image 45
Oliver Charlesworth Avatar answered Sep 20 '22 01:09

Oliver Charlesworth


don't think this will be possible, because you can never interface it back to Variable. This is what i mean

int a=0; int b = 0;
Variable<int>* derived = new Derived();
derived->Callback(a, b); //this won't compile because Variable<int> does not have Callback with 2 vars.
like image 45
RvdK Avatar answered Sep 22 '22 01:09

RvdK


I know this there is an accepted answer, but there is one (ugly) way to achieve what you want, although I would not recommend it:

template <typename T> 
class Variable 
{ 
public: 
  Variable (T v) : m_value (v) {}
  virtual void Callback (const char *values, ...) = 0; 

private: 
  T m_value; 
};

class Derived : public Variable<int> 
{ 
public: 
  Derived (int v) : Variable<int> (v) {} 
  virtual void Callback (const char *values, ...) {
  } 
};  

Now, you can use:

  int a=0; 
  double b = 0; 
  Variable<int>* derived = new Derived(3); 
  derived->Callback("");
  derived->Callback("df", a, b);

You need the values argument in order to obtain the remaining arguments inside the method. You also need to know the argument types, and pass them like printf does.

This method is error prone, as you must match the argument types on values with the real argument types.

like image 39
J. Calleja Avatar answered Sep 19 '22 01:09

J. Calleja