Let's say we have the following Base
class, and two derived classes Derived1
and Derived2
:
class Base {
// Some declarations ...
};
class Derived1 : public Base {
// Some declarations ...
public:
vector<int> _array;
};
class Derived2 : public Base {
// Some declarations ...
public:
vector<int> &_array;
};
That is, we have a common class but the underlying data structures are of different types.
Say that we want to access individual elements of the underlying arrays using a uniform interface from a Base
pointer. i.e. something like this:
Base *bPtr = new Derived1(...);
int val = bPtr->index(3);
Having a pure virtual function called index
in Base
is one solution. However, in that case we would need the same int index(uint x) { return _array[x]; }
implementation in both of the derived classes. This is ugly, and we cannot implement that function in Base
since it does not know about _array
.
So we must either (1) change the types of _array
s to the same type (say, to a vector<int>*
) and have the implementation of index
in Base
or (2) have two implementations in Derived1
and Derived
in order to make use of a common interface. However I cannot afford (1) since it would add an extra indirection layer to Derived1
, and I want to avoid that if possible. Having a number of member variables like that makes (2) horrible since that is a lot of boilerplate and replication, and hard to maintain.
I understand that the two index
functions are actually different functions, since they operate on different types. In many other scenarios Derived1
and Derived2
would need separate functions since they have different behaviour (and would be compiled to different object codes). However in the case of C++ the implementations are syntactically similar, so I'm wondering whether there is a way to exploit that.
One possible solution is having a free function:
template <class T>
int index(const T &obj, uint x) {
return obj._array[x];
}
where we declare index
a friend of both Derived1
and Derived2
. However, this might not be considered elegant since it uses a friend declaration (also declaring friend twice is repetitive).
Hence, my question is: Is there a more elegant way to implement index
, while avoiding performance costs and code repetition?
Aucun commentaire:
Enregistrer un commentaire