简体   繁体   中英

How to allow subclasses to have a common base class but accept different types of arguments in their methods

I hope the title best fits my question but I'll explain further.

I have two data types I'm using (a Matrix supported by the Eigen library and a pair of STL maps keyed by strings holding int values).

I would like to allow my code to work with both of them as generically as possible. So I started by creating an abstract base class including basic operations I required (insert, get "row" etc.) and trying to derive two sub classes to wrap my data types(one for matrix and one for my pair) implementing the inner functions as I needed.

This worked well for a while but then I encountered some typing problems, since my matrix is indexed by integers and the hash maps are indexed by strings (they both represent the same data type just in different ways). When I attempted to write code that retrieved a "row" I was stuck since I know I can't declare a method in my base class and then override it with different argument types (the matrix retrieves a row by a numeric index and the maps retrieve it by string).

Is there a common way to do this without the overuse of templates for each subclass ?

A code example might make it clear (forgive any mistakes as this is just an example):

class BaseClass {
public:
 virtual GenericRowType getRow(???? index)=0;
}

class MatrixWrapper : public BaseClass{
 // Should be: GenericRowType getRow(int index);
}

class MapsWrapper : public BaseClass{
 // Should be: GenericRowType getRow(string index);
}

You can use templates:

template <typename T>
class BaseClass {
public:
 virtual GenericRowType getRow(T index)=0;
}

class MatrixWrapper : public BaseClass<int>{
 // Should be: GenericRowType getRow(int index);
}

class MapsWrapper : public BaseClass<string>{
 // Should be: GenericRowType getRow(string index);
}

This is a classical case for using templates. You should make the BaseClass a template with one class template parameter and then the inherited classes will inherit to a template specialization:

template <class T>
class BaseClass {
  public:
    virtual GenericRowType getRow(T index) = 0;
};

class MatrixWrapper : public BaseClass<int> {
  public:
    GenericRowType getRow(int index);
};

class MapsWrapper : public BaseClass<std::string> {
  public:
    GenericRowType getRow(std::string index);
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM