1

Suppose I was given an abstract class,

class A
{
 public:
  A(){};
  virtual ~A(){};

  virtual float func(const int in1, const int in2, const int in3) = 0;

  //
  // Some default useful functions
  //
 private:
  //
  // Some infrastructure code
  //
};

In most of the cases it works just fine

class A1 : public A
{
 public:
  A1(){};
  virtual ~A1(){};

  virtual float func(const int in1, const int in2, const int in3)
  {
    // Do something to in1, in2, in3 to get output
  }
};

But lets say for A20 I need to pass an additional argument to make the function work yet I still want to use this abstract class because everything else is similar beside this additional argument. The only way I can think of is passing the parameter through the constructor and store a copy. Is this work around consider as good practice?

class A20 : public A
{
 public:
  A20(const int in4) : m_in4(in4){};
  virtual ~A20(){};

  virtual float func(const int in1, const int in2, const int in3)
  {
    // Do something to in1, in2, in3, m_in4 to get output
  }

 private:
  int m_in4;
};

If not what is the best way to do it? Is it better to duplicate another abstract class with 4 inputs for the function? Or is it better to make A20 independent of A and duplicate "Some default useful functions" and "Some infrastructure code" from A into A20?

EDIT: paddy's comment

user3667089
  • 2,996
  • 5
  • 30
  • 56
  • 1
    Difficult to comment on the design without context. If the extra value you set in the constructor remains the same for the object's lifetime, I would say that's ok. – Neil Kirk Dec 01 '15 at 02:57
  • Maybe c++ 11 virtual function overloading would be helpful for you? http://stackoverflow.com/questions/15827632/overload-of-pure-virtual-function –  Dec 01 '15 at 02:58
  • 1
    It's perfectly fine to do this. But whether it is good design in your case may really depend on the meaning of `func` and how that extra parameter relates to the other ones that are passed. Side note: you should use an initializer list to set that member variable: `A20( const int in4 ) : m_in4( in4) {}` – paddy Dec 01 '15 at 02:58
  • @PatrickH override cannot overload virtual functions with different number of arguments, you solution requires to add a non pure virtual function with 4 inputs in the abstract class, am I right? – user3667089 Dec 01 '15 at 03:10
  • @user3667089 Here's another example of overloading a pure virtual function. http://stackoverflow.com/questions/23955177/overloading-pure-virtual-function-with-different-set-of-arguments I figure you can do that your class A20? –  Dec 01 '15 at 03:48
  • @PatrickH No, the link you shown is using dynamic casts, it only works if lets say I want to pass in3 as a float. It's doesn't work in the case when an additional argument needed for the function. – user3667089 Dec 01 '15 at 05:03
  • @user3667089 Ok, never mind that. The simplest way is to make a separate abstract class. Then inherit and implement any combination there of. As well, there is making use of variadics. http://en.cppreference.com/w/cpp/utility/variadic ... Still you might not need that much. –  Dec 01 '15 at 15:13

1 Answers1

0

I think one way of doing it would be to add an additional optional parameter to base class A.

class A
{
 public:
  A(){};
  virtual ~A(){};

  virtual float func(const int in1, const int in2, const int in3, int 4 = some_def_value) = 0;

  //
  // Some default useful functions
  //
 private:
  //
  // Some infrastructure code
  //

You should keep this default value consistent and not override it in the overriding function of class A20.

  • Thought of it but I heard using default parameters is bad practice. Also this doesn't seem to flexible what if I have a A30 that wants to pass a 4th argument as a float? – user3667089 Dec 01 '15 at 03:14
  • 1
    It is a bad practice when you don't keep the default values consistent across implementations. If you want to make it more flexible, you could either opt to go with a template or possibly a void pointer... – Danh Thanh Nguyen Dec 01 '15 at 03:52