Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gmmastros on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Template class problems with declaring type

Status
Not open for further replies.

jdf442

Programmer
Oct 17, 2010
10
AU
hey guys, I have created my own templated container class called Container to hold other class objects in my program.

My program has two classes:
1. Numbers
2. Letters

When the program runs the user enters a filename with the firstline being the class type (being a 1 for class type Numbers and a 0 for class type Letters). eg: 1 or 0
The second line has the number of Numbers/Letters. eg: 4
And the last line has the Letters/Numbers seperated by a space. eg: 1 2 3 4 or a b c d

//******* CODE ***********
Code:
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include <typeinfo>
#include <string>
#include <iomanip>

using namespace std;

class Numbers
{
  friend istream& operator>>(istream& in, Numbers& num);
private:
     int value;
 public:
        Numbers();
        Numbers(int);      
};

istream& operator>>(istream& in, Numbers& num)
{
 in>>num.value;
 return in;         
}

Numbers::Numbers()
{
 value = 0;    
}

Numbers::Numbers(int val)
{
 if(val < 0)
 {
  cout<<"Error - Must be a number > 0!"<<endl;
  exit(1);     
 }
 else
     value = val;              
}

//**********************************************

class Characters
{
friend istream& operator>>(istream& in, Characters& chars);
 private:
         char value;
 public:
        Characters();
        Characters(char);     
};
 
istream& operator>>(istream& in, Characters& chars)
{
 in>>chars.value;
 return in;         
}

Characters::Characters()
 {
  value = 'a';           
 }
 
 Characters::Characters(char mychar)
 {
  if(!islower(mychar))
  {
   cout<<"Error - Must be a lowercase letter!"<<endl;
   exit(1);                  
  }
  value = mychar;               
 }

//**********************************************

template<class T>
class Container
{
 private:
         T *data;
         int size;
 public:
        Container();
        Container(T *d, int s);
        ~Container();
        void display();  
};

template <class T>
Container<T>::Container()
{
 data = NULL;
 size = 0;                    
}

template <class T>
Container<T>::Container(T *d, int s)
{
 data = d;
 size = s;                 
}

template <class T>
Container<T>::~Container()
{
 delete [] data;                        
}

template <class T>
void Container<T>::display()
{
 cout<<"Container data: ";
 for(int i = 0; i < size; i++)
 {
  cout<<data[i]<<" ";        
 }
 cout<<endl;    
}

//************************** MAIN ***************************

int main()
{
 int classType;
 int size;
 char filename[100];

 cout<<"Enter filename: ";
 cin>>filename;
 ifstream input;
 
 input.open(filename);
 if(!input.good())
 {
  cout<<"Error - Invalid filename: "<<filename<<endl;
  exit(1);                 
 }
 
 input>>classType>>size;
 
 if(classType == 0)
 {
  Numbers *temp;
  temp = new Numbers[size];             
 }
 else if(classType == 1)
 {
  Characters *temp;
  temp = new Characters[size];    
 }
 else
 {
  cout<<"Error - Invlaid class type: "<<classType<<", must be 1 or 0!"<<endl;
  exit(1);    
 }
 
 for(int i = 0; i < size; i++)
 {
  input>>temp[i];        
 }
 Container<typeid(temp)> mycontainer;

    return 0;
}
//******* END CODE ***********


I want to be able to open the text file and based on what the classtype is (1 or 0) create an array of objects to read the data from the file into class and then store these class objects (Numbers/Letters) in my containier class so i can proccess them.


I am having trouble with how to declare what type of class it is based on the classtype i read in from the file and also how to declare what the container class is going to hold based on the classtype???????

Does anyone have any suggestions??? You help will be much appreciated!

Cheers!
 
One way would be to create a base class which the Numbers class and the Characters each derive from.

Code:
SomeBaseClass
{
int type;
}

class Characters : Public SomeBaseClass

Then using:

Code:
Conainter<SomeBaseClass>* Temp;

you can capture the information(the type), and depending on the type you can use

Code:
static_cast<YourDerivedType>(Temp)->someOperation

also, don't the individual definitions of Numbers* temp and Characters* temp lose their scope as soon as the if() check finishes..?
 
Hey, Thanks for the reply. Is there anyway of doing typecasting without having to create a base class??
 
Or what if i make the Container class a friend of the Numbers and Letters class?
 
dynamic_ and static_ casting is generally reserved for working your way up and down a class hierarchy. Your base class can be as simple and the ctor(), the dtor(), and your type variable. shouldnt be anything more than a handful of lines and then add
Code:
Class Numbers [b][COLOR=red]: Public BaseClass[/color][/b]

 
Regrettably, SDowd's approach is wrong, it does not work. It's impossible to create heterogeneous Container with Number and Letter elements in such a way.

As we can see you need two distinct Containers: Container<Number> and Container<Letter>. Now you can split your input code: the 1st branch for numbers and the 2nd for Letters (that's why the 1st input line contains 1 or 0).

Besides that never use exit() function in C++ programs. On exit(code) call the program terminates "without leaving the current block and hence without destroying any objects with automatic storage duration" (The C++ Standard, 3.6.1). Use return 1 in main function or throw exception in other functions.

Apropos, why a class with a SINGLE number (or letter) value has name NumberS (or LetterS') ?..
 
ArkM,
I was suggesting that the container's definition could be casted once the initial type was read in. With the base reading in the type, then based on that type cast accordingly. Is that wrong? and if so, why?
 
SDowd,

the key point is: what's the container type in Container<type> declaration? If it's a base type, we can save only this type parts of derived type objects in the container.

Possible straightforward solution of the problem: define template container with pointers to the polymorphic base class with virtual functions, then save dynamic copies of derived class objects. Now extract pointers or references to the base class for container elements.

I'm afraid that this mechanics is out of OP scope...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top