class A {};
class B : public A{
int b;
};
class C : public A{
int c;
};
template <class T, class Y> //generic function
foo(T TestObject)// TestObject could be an instance of B or C or any other //classes which it is inherited from A. The inherited classes has only one //member from the type integer.
{
Y IntegerVarValue = TestObject.IDENTIFIER; // here is the problem. How could I //know the identifier name of the member variable?
}
Since the testObject is declared and passed as function argument, how can I get access to its member variable despite I do not know its identifier name //and know only its data type, in this case an integer, because the function is generic and I do not know how many classes will be inherited from A, but I only know that the inherited classes has only one member variable from one specific data type.
I appreciate any suggestion...
B and C can have get/set member functions with the same name that you use in foo.
You probably don't need to use both inheritance and templates here. If you use templates you don't need the class A.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class B{
public:
int get() const {return b;}
private:
int b;
};
class C{
public:
int get() const {return c;}
private:
int c;
};
template <class T, class Y> //generic function
void foo(T TestObject)
{
Y IntegerVarValue = TestObject.get();
}
That could be a good solution. However, suppose we have a parent class which we have to inherit from, given from one vendor, and there are rules how to extend the child classes. If you are not allowed to implement such member function. How could you access the member variables as described above?
class A
{
public:
virtualint get() const = 0;
};
class B : public A{
public:
virtualint get() const {return b;}
private:
int b;
};
class C : public A{
public:
virtualint get() const {return c;}
private:
int c;
};
void foo(A& TestObject)
{
int IntegerVarValue = TestObject.get();
}
There is no way to get access a variable without knowing its name.
This is poor use of templates. What you need is a better structure with some sort of common interface. Either add int member to A or a virtual get, as Peter suggested.
It is really irrelevant for this particular problem that B, C etc. are derived from a common base class.
One possibility is to give the member variable the same identifier (name) in each class.
If that is not possible, a non-intrusive way (ie. one that does not require any modification of these classes) is to write an external accessor function which is overloaded or specialized for each derived class.
#include <iostream>
struct A {};
struct B : A { int b = 5 ; };
struct C : A { int c = -9 ; };
template < typename T > int accessor( const T& object ) ; // generalization is not defined
template< typename T > void foo( T& object )
{
int value = accessor(object) ;
std::cout << value << '\n' ; // use value
}
int accessor( const B& object ) { return object.b ; }
int accessor( const C& object ) { return object.c ; }
int main()
{
B b ;
C c ;
foo(b) ;
foo(c) ;
}