Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove unwanted functions from interface

I have an interface class MyFunction. There are three functions in this class with the following signatures:

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList) = 0;

Now, any implementation of MyFunction will only need to implement one of these functions depending on what type of value it needs to return. But I'll have to implement all 3 functions even if the other two functions are like this:

virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}

which doesnt look so good. Or, I can declare all three functions like this in the interface:

virtual bool Eval(int& iReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}
virtual bool Eval(double& dReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}
virtual bool Eval(char*& zReturnVal, size_t szArgumentCount, list<Param> lParameterList){return false;}

Which also looks ugly. What is the less ugly of these two? Or is there a better way to do this?

EDIT:

On D Krueger's method :

#include <iostream>

using namespace std;

class Base
{
    public:
        template<typename T>
            void F(T){cout << "Type T" << endl;}
};

class Imp : public Base
{
    public:
        template<int>
            void F(int){cout << "Type int" << endl;}
};

int main(int argc, char** argv)
{
    Base* pB;
    Imp oI;
    pB = &oI;

    pB->F(1);
}

Looks like specialization does not apply across classes though derived. As template functions can't be virtual, this is a hopeless situation it seems.

like image 432
nakiya Avatar asked Oct 21 '10 04:10

nakiya


2 Answers

Since there is a one-to-one mapping between the types used in Eval() and the number of implementations, a template member function should work.

class MyFunction {

    template <class T>
    bool Eval(T& returnVal, size_t szArgumentCount, list<Param> lParameterList) 
        { return false; }
};

Then implement the specializations for the types that shouldn't return false.

This requires only the single generic implementation to return false and the three implementations that would be needed in any case.

like image 188
D Krueger Avatar answered Sep 25 '22 18:09

D Krueger


It's a sign that your interface-design could need to be refactored, when the classes implementing the interface did not need the whole amount of methods in it. Perhaps you could divide this interface into 3 interfaces.

Another possibility would be to create a wrapper-interface from that, which returns default values for the unneeded 2 methods. But in this case you would end up with 3 interfaces as well (and the original parent-interface -> 4 interfaces total). This solution would be acceptable if you have no possibility of changing the original interface.

like image 42
MOnsDaR Avatar answered Sep 21 '22 18:09

MOnsDaR