ttrrxx
ttrrxx

Reputation: 61

interface implementation with additional default arguments?

I have a question about implementing interface in C++:

Suppose there is an interface:

class A
{
 virtual void f() = 0;
};

When implementing this, I wonder if there's a way to do something like:

class B : public A {     
  void f(int arg=0) {....} // unfortunately it does not implement f() this way
};

I want to keep the iterface clean. When client code calls through public interface A, arg is always set to 0 automatically. However when I call it through B, I have the flexibility to call it with arg set to some different value. Is it achievable?

EDIT: Since I control the interface and implementation, I am open to any suggestions, Macros, templates, functors, or anything else that makes sense. I just want to have a minimal and clean code base. The class is big, and I don't want to write any code that not absolutely necessary - e.g. another function that simply forwards to the actual implementation.

EDIT2: Just want to clarify a bit: The public interface is provided to client. It is more restrictive than Class B interface, which is only used internally. However the function f() is essentially doing the same thing, other than minor different treatment based on input arg. The real class has quite some interface functions, and the signature is complex. Doing function forwarding quickly results in tedious code repetition, and it pollutes the internal interface for B. I wonder what is the best way to deal with this in C++.

Thanks!

Upvotes: 2

Views: 445

Answers (4)

Keldon Alleyne
Keldon Alleyne

Reputation: 2130

Doing function forwarding quickly results in tedious code repetition, and it pollutes the internal interface for B. I wonder what is the best way to deal with this in C++.

It sounds like you need to write a script to automate part of the process.

Upvotes: 0

Arne Mertz
Arne Mertz

Reputation: 24626

From your descriptions I'd say you should provide two classes, both with a specific responsibility: One to implement the desired functionality, the other to provide the needed interface to the client. That way you separate concerns and dont violate the SRP:

class BImpl {
public:
  doF(int arg);  
};

class B : public A {
  BImpl impl;
public:
  virtual void f() override {
    impl.doF(0);
  }
};

Upvotes: 0

Mats Petersson
Mats Petersson

Reputation: 129514

When you have an interface, the basic principle should be that a function ALWAYS takes the same arguments and ALWAYS operates in the same way, no matter what the derived class is doing. Adding extra arguments is not allowed, because that presumes that the "thing" that operates on the object "knows" what the argument is/does.

There are several ways around this problem - thre that spring to mind immediately are:

  1. Add the argument to the interface/baseclass.
  2. Don't use an argument, but some extra function that [when the derived object is created or some other place that "knows the difference"] stores the extra information inside the object that needs it.
  3. Add another class that "knows" what the argument is inside the class.

An example of the second one would be:

class B: public A
{  
   private:
     int x; 
   public:
     B() x(0) { ... }   // default is 0. 
     void f() { ... uses x ... }
     void setX(int newX) { x = newX; };
     int getX() { return x; }
};

So, when you want to use x with another value than zero, you call bobject->setX(42); or something like that.

Upvotes: 2

nneonneo
nneonneo

Reputation: 179687

Yes, just make two separate functions:

class B : public A {     
    void f() { return f(0); }
    void f(int arg) { .... }
};

Upvotes: 2

Related Questions