How to get the user select a type

Hi,

Here in this code, "ob" doesn't work after the conditions, and that's because it has been created inside those blocks.
Is there a way to receive the type from the user and then be able to use that specific type of object "outside" its creation block, as well?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace std;

template <class T>
class test {
public:
	void foo(T t) { cout << t << endl; }
};

int main()
{
	int n;
    cout << "For int press 1 and for double press 2\n"; 
	cin >> n;

	if (n == 1) {
		test<int> ob; ob.foo(12);
	}
	else if (n == 2) {
		test<double> ob; ob.foo(5.5);
	}

	ob  // here 'ob' deosn't work. 

	return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
using namespace std;

class Ob
{
public:
   virtual ~Ob(){};
   virtual void foo(){ cout << "Hi, I'm a basic Ob\n"; }
};

class Obi : public Ob
{
   int i;
public:
   Obi( int i_ ) : i(i_){}
   ~Obi(){};
   void foo(){ cout << "Hi, I'm an int with value " << i << '\n'; }
};

class Obd : public Ob
{
   double d;
public:
   Obd( double d_ ): d(d_){}
   ~Obd(){};
   void foo(){ cout << "Hi, I'm a double with value " << d << '\n'; }
};


int main()
{
   Ob *p;

   int n;
   cout << "Enter 1 for int, 2 for double: ";   cin >> n;

   switch( n )
   {
      case 1: p = new Obi(5);   break;
      case 2: p = new Obd(12.5);   break;
      default: p = new Ob;   break;
   }
   p->foo();
   delete p;
}
Last edited on
But for a much bigger class and three different types, we can't duplicate the whole class three times. Isn't there an easier way, please?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <typeinfo>
using namespace std;

class Ob
{
public:
   virtual ~Ob(){};
   virtual void foo(){ cout << "Hi, I'm a basic Ob\n"; }
};

template<typename T> class ObT : public Ob
{
   T value;
public:
   ObT( T v ) : value(v) {}
   ~ObT(){};
   void foo(){ cout << "Hi, I'm a " << typeid(T).name() << " with value " << boolalpha << value << '\n'; }
};


int main()
{
   Ob *p;

   int n;
   cout << "Enter 1 for int, 2 for double, 3 for char, 4 for bool: ";   cin >> n;

   switch( n )
   {
      case 1: p  = new ObT<int>   (5   );   break;
      case 2: p  = new ObT<double>(12.5);   break;
      case 3: p  = new ObT<char>  ('A' );   break;
      case 4: p  = new ObT<bool>  (true);   break;
      default: p = new Ob;                  break;
   }
   p->foo();
   delete p;
}

Last edited on
thank you, that's simpler.
But if we could empty the class Ob and the code still worked, that would be very great. (because the functions are many).
Yes, but you don't need more than a very basic member function in class Ob. For example
virtual void foo(){}
would do.

I'm at the limit of my expertise here; I don't see any other way of getting functions into the vtable.

Maybe other users have better ideas.
Yes, I understand, for example, for ten functions (foo_1() to foo_10(), for example) in ObT, we need something like in Ob:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Ob
{

public:
   virtual ~Ob(){};

   virtual void foo_1(){  }
   virtual void foo_2(){  }
   virtual void foo_3(){  }
   virtual void foo_4(){  }
   virtual void foo_5(){  }
   virtual void foo_6(){  }
   virtual void foo_7(){  }
   virtual void foo_8(){  }
   virtual void foo_9(){  }
   virtual void foo_10(){  }

};


And it's only public data. We might have some private data too!
That is, for every data and function in ObT, we need its alike name in Ob.
Last edited on
frek wrote:
That is, for every data and function in ObT, we need its alike name in Ob.

For every function member or data member that you intend to address by a base-class pointer, yes. But you can have data members (e.g. value in the above example) that aren't in ob. And many of the functions may not depend on type: you could simply define them once in the base class and let the templated classes inherit them.

Perhaps you could say what your intended application is: it may not be the appropriate way of solving the problem anyway.

Modern Fortran has the concept of an "unlimited polymorphic type", but I'm not sure that there is anything like it in c++.
Last edited on
Topic archived. No new replies allowed.