Interview Question
Country: United States
Yes you can.
One simple way is to create a class say A, extend with with different subclasses(class B for int, class C for float etc),
Then use an array of pointers to base class (A), and use it to store objects of derived classes.
I'm not a Java expert, but I think you're talking about the Object class that is the parent for any other class?
You can use the void* type as the generic type. At the end of the day, all you need to store from the object is a "pointer" to it.
vector<void*> arr;
int *a = new int;
*a = 1;
double* b = new double;
*b = 2.0;
Type* t = new Type();
arr.push_back(a);
arr.push_back(b);
arr.push_back(t);
Type* tt = (Type*) arr[2];
however, I would not suggest this. Since (void*) does not carry any information about type. The better approach, is (as suggested above) use some inheritance. As it is in C#, Java, etc. (Object class).
use of template..
#include <iostream.h>
template <class T>
class collection {
private:
T n;
public :
void store_data(){
cin>> n;
}
void display_data(){
cout << " given data "<< n <<"\n";
}
};
main(void){
collection <int> obj1;
collection <float> obj2;
cout <<" enter integers\n";
obj1.store_data();
cout<< " enter floating no \n";
obj2.store_data();
obj1.display_data();
obj2.display_data();
}
should be smth like this:
class Base { // base class for wrapper classes
public:
virtual ~Base() {}
};
template <class T> // generic wrapper class
class Wrapper : public Base {
T object;
public:
Wrapper(const T& obj) : object(obj) {
}
Wrapper(T&& obj) : object(std::move(obj)) {
}
Wrapper() {}
operator T() { return object; }
};
class Collection {
std::vector < std::unique_ptr< Base >> v;
public:
Collection() {}
template < class T >
void insert(const T& t) {
v.push_back(std::unique_ptr< Base >(new Wrapper<T>(t)));
}
template < class T >
void insert(T&& t) {
using T2 = typename std::remove_reference<T>::type;
v.emplace_back(new Wrapper< T2 >(std::forward<T>(t)));
}
// try to convert an i-th object to type 'T'
template < class T >
bool assign(T& t, unsigned idx) {
if(idx >= v.size())
return false;
Wrapper<T>* wp = dynamic_cast<Wrapper<T>*>(v[idx].get());
if (wp == 0)
return false;
t = *wp;
return true;
}
};
struct YOYO {
};
int main(int argc, char* argv[]) {
Collection c;
YOYO yoyo;
int aaa = 2;
std::string xxx("123123");
c.insert(12);
c.insert(yoyo);
c.insert(YOYO());
c.insert(std::string("123123"));
c.insert(xxx);
int aaa;
if(c.assign(aaa, 0)) {
std::cerr << "got x value = " << aaa << "\n";
}
if(c.assign(yoyo, 2)) {
std::cerr << "got YOYO value\n";
}
return 0;
}
Thanks. Following above suggestion..tried some code. For simplicity using array, but it can always be extended to user defined collection classes.
- learner123 April 22, 2014#include <iostream>
using namespace std;
class BaseDataType
{
public:
virtual void print() = 0;
};
class IntDataType: public BaseDataType
{
int m_x;
public:
void print()
{
cout << "IntDataType" << endl;
}
};
class FloatDataType: public BaseDataType
{
float m_x;
public:
void print()
{
cout << "FloatDataType" << endl;
}
};
class DoubleDataType: public BaseDataType
{
double m_x;
public:
void print()
{
cout << "DoubleDataType" << endl;
}
};
int main()
{
BaseDataType* a[3];
a[0] = new IntDataType;
a[1] = new FloatDataType;
a[2] = new DoubleDataType;
for(int i = 0; i < 3; ++i)
{
a[i]->print();
}
return 0;
}