3 Replies - 1584 Views - Last Post: 29 April 2010 - 12:56 PM Rate Topic: -----

#1 Odaym  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 30
  • Joined: 06-January 10

Problem with Typeid

Posted 29 April 2010 - 11:11 AM

I'm sorry for the huge amount of code, but i thought i should paste it all so i could get a definitive answer.
There are 4 types of Employees (daily, hourly, monthly, and monthlyComission), each of them has a date of birth, the super class Employee has DOB from Date as composition. The rest are inheriting from Employee.
I have to create different objects of those different classes and enter them into an array of pointers, find out which are the ones that are Monthly, and print only those.
for starters, i only want to print all their types using Typeid, then i want to use typeid to find out which one of them is Monthly and print only those ones.
doesn't the following look right?
it gives the following warning : "warning C4541: 'typeid' used on polymorphic type 'class Employee' with /GR-; unpredictable behavior may result"
I'm really lost here, because i dont really understand how typeid works

#include <iostream>
#include <cstring>
#include <typeinfo>

using namespace::std;

//BEGINNING OF CLASS Date IMPLEMENTATION

class Date{
private:
	int day;
	int month;
	int year;
	int checkDay (int) const;
public:
	Date (int = 1,int = 1,int = 1900);
	void print () const;
};

//BEGINNIG OF PUBLIC FUNCTIONS IMPLEMENTATION (class Date)

Date::Date (int d,int m,int y)
{
	if (m > 0 && m <= 12)
		month = m;

	else
	{
		month=1;
		cout <<m<<" is an invalid month. Month is now set to 1."<<endl;
	}

	day = checkDay (d);

	if (y >= 1900 && y <= 2010)
		year = y;

	else
	{
		year = 1900;
		cout <<y<<" is an invalid year, year is now set to 1900."<<endl;
	}
}

int Date::checkDay (int d) const
{
	static const int daysPerMonth[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

	if (d > 0 && d <= daysPerMonth[month])
		return d;

	if (month == 2 && d == 29 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))
		return d;
	
	cout <<d<<" is an invalid day. Day is now set to 1."<<endl;
	return 1;
}

void Date::print () const
{
	cout <<"Born on : "<<day<<" / "<<month<<" / "<<year<<endl;
}

//BEGINNING OF CLASS Employee INTERFACE

class Employee{
private:
	char *Fname;
	char *Lname;
	const Date dob;
public:
	Employee (char*,char*,const Date&);
	~Employee ();
	char* getFname () const;
	char* getLname () const;
	virtual void print () = 0;
	virtual int calSalary () = 0;
};

//BEGINNING OF PUBLIC FUNCTIONS IMPLEMENTATION (class Employee)

Employee::Employee (char *fn,char *ln,const Date &d):dob(d)
{
	int f = strlen (fn);
	Fname = new char[f + 1];
	strncpy (Fname,fn,f);
	Fname[f] = '\0';

	int l = strlen (ln);
	Lname = new char[l + 1];
	strncpy (Lname,ln,l);
	Lname[l] = '\0';
}

Employee::~Employee ()
{
	delete[] Fname;
	Fname = 0;

	delete[] Lname;
	Lname = 0;
}

char* Employee::getFname () const
{
	return Fname;
}

char* Employee::getLname () const
{
	return Lname;
}

//BEGINNING OF CLASS HourlyEmployee INTERFACE

class HourlyEmployee:public Employee{
private:
	int nbh;
	int rph;
public:
	HourlyEmployee (char*,char*,const Date&,int,int);
	int calSalary ();
	void print ();
};

//BEGINNING OF PUBLIC FUNCTIONS IMPLEMENTATION (class HourlyEmployee)

HourlyEmployee::HourlyEmployee (char *fn,char *ln,const Date &d,int nb,int rp):Employee(fn,ln,d)
{
	nbh = nb;
	rph = rp;
}

int HourlyEmployee::calSalary ()
{
	return nbh * rph;
}

void HourlyEmployee::print ()
{
	cout <<"The First name is : "<<getFname ()<<endl;
	cout <<"The Last name is : "<<getLname ()<<endl;
	cout <<getFname ()<<" "<<getLname ()<<" is an hourly employee."<<endl;
	cout <<"The salary is : " <<calSalary()<<endl;
}

//BEGINNING OF CLASS DailyEmployee INTERFACE

class DailyEmployee:public Employee{
private:
	int nbd;
	int rpd;
public:
	DailyEmployee (char*,char*,const Date&,int,int);
	int calSalary ();
	void print ();
};

//BEGINNING OF PUBLIC FUNCTIONS IMPLEMENTATION (class DailyEmployee)

DailyEmployee::DailyEmployee (char *fn,char *ln,const Date &d,int nb,int rp):Employee(fn,ln,d)
{
	nbd = nb;
	rpd = rp;
}

int DailyEmployee::calSalary ()
{
	return nbd * rpd;
}

void DailyEmployee::print ()
{
	cout <<"The First name is : "<<getFname ()<<endl;
	cout <<"The Last name is : "<<getLname ()<<endl;
	cout <<getFname ()<<" "<<getLname ()<<" is a daily employee."<<endl;
	cout <<"The salary is : " <<calSalary()<<endl;
}

//BEGINNING OF CLASS MonthlyEmployee INTERFACE

class MonthlyEmployee:public Employee{
private:
	int MSalary;
public:
	MonthlyEmployee (char*,char*,const Date&,int);
	int calSalary ();
	void print ();
};

//BEGINNING OF PUBLIC FUNCTIONS IMPLEMENTATION (class MonthlyEmployee)

MonthlyEmployee::MonthlyEmployee (char *fn,char *ln,const Date &d,int ms):Employee(fn,ln,d)
{
	MSalary = ms;
}

int MonthlyEmployee::calSalary ()
{
	return MSalary;
}

void MonthlyEmployee::print ()
{
	cout <<"The First name is : "<<getFname ()<<endl;
	cout <<"The Last name is : "<<getLname ()<<endl;
	cout <<getFname ()<<" "<<getLname ()<<" is a monthly employee."<<endl;
	cout <<"The salary is : " <<calSalary()<<endl;
}

//BEGINNING OF CLASS MCEmployee INTERFACE

class MCEmployee:public MonthlyEmployee{
private:
	int comrate;
	int sales;
public:
	MCEmployee (char*,char*,const Date&,int,int,int);
	int calSalary ();
	void print ();
};

//BEGINNING OF PUBLIC FUNCTIONS IMPLEMENTATION (class MCEmployee)

MCEmployee::MCEmployee (char *fn,char *ln,const Date &d,int ms,int com,int sal):MonthlyEmployee(fn,ln,d,ms)
{
	comrate = com;
	sales = sal;
}

int MCEmployee::calSalary ()
{
	return ((comrate * sales) + (MonthlyEmployee::calSalary ()));
}

void MCEmployee::print ()
{
	cout <<"The First name is : "<<getFname ()<<endl;
	cout <<"The Last name is : "<<getLname ()<<endl;
	cout <<getFname ()<<" "<<getLname ()<<" is a monthly commission employee."<<endl;
	cout <<"The salary without commission is : "<<MonthlyEmployee::calSalary()<<endl;
	cout <<"The salary with commission is : "<<calSalary()<<endl;
}

//BEGINNING OF DRIVER (main)

int main ()
{	
	//vector <Employee *> employees (8);
	Employee *employees[8];

	Date hed (13,04,1966);
	HourlyEmployee he ("Oday","Maleh",hed,39382,4);
	employees[0] = &he;

	Date hed2 (5,6,1985);
	HourlyEmployee he2 ("Malak","Helo",hed2,22287,54);
	employees[1] = &he2;

	Date ded (04,9,1983);
	DailyEmployee de ("Salah","Bakri",ded,6599,20);
	employees[2] = &de;

	Date ded2 (12,11,1955);
	DailyEmployee de2("Samar","Merhi",ded2,4812,421);
	employees[3] = &de2;

	Date med (12,12,1938);
	MonthlyEmployee me ("Malek","Salah",med,68300);
	employees[4] = &me;

	Date med2 (1,2,1923);
	MonthlyEmployee me2 ("Lamia","Somaii",med2,58488);
	employees[5] = &me2;

	Date mced (26,2,2008);
	MCEmployee mce ("Baker","Elie",mced,40000,0.09f,458000);
	employees[6] = &mce;

	Date mced2 (3,3,1967);
	MCEmployee mce2 ("Jaafar","Ali",mced2,1000,0.04f,51000);
	employees[7] = &mce2;
	
	for (int i = 0; i < 8; i++)
	{
		cout <<"The type of all objects starting from the first is : "
			<<typeid(*employees[i]).name()<<endl;
	}

	return 0;
}


thank you in advance, very much

Is This A Good Question/Topic? 0
  • +

Replies To: Problem with Typeid

#2 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Problem with Typeid

Posted 29 April 2010 - 11:25 AM

This has to do with RTTI. Search through project options, and turn /GR on. Right now, it is disabled, and the Compiler does not know if "employees[i]" is either an object of base class, or derived class(es), therefore typeid can't be used (may occur in runtime error if you force the execution).
EDIT: What Compiler do you use?

This post has been edited by sarmanu: 29 April 2010 - 11:33 AM

Was This Post Helpful? 0
  • +
  • -

#3 Odaym  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 30
  • Joined: 06-January 10

Re: Problem with Typeid

Posted 29 April 2010 - 12:28 PM

thank you very much, that solved it. :)
i want to ask another thing..

if let's say..I have the following..

char choice[20];

	cout <<"Choose a class [Hourly, Daily, Monthly, MCEmployee]\nto preview its objects [class ClassName] : ";
	cin >> choice;

	int f = strlen (choice);
	char* Name = new char[f + 1];
	strncpy (Name,choice,f);
	Name[f] = '\0';

	for (size_t i = 0; i < employees.size(); i++)
	{
		if (strcmp ((typeid(*employees[i]).name ()),Name) == 0)
		{
			employees[i]->print();
		}
		else
			cout <<"No such class."<<endl;
	}


the above means, when the user enters "class HourlyEmployee", compare it to what typeid returns from every object, and if it's true, print that object's information, but it's not working, because i dont think what the user is entering is matching the type, i get 8 "No such class", because the characters or i think the space bar is not being counted, i really dont know, any help is appreciated very much, thank you!
Was This Post Helpful? 0
  • +
  • -

#4 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Problem with Typeid

Posted 29 April 2010 - 12:56 PM

You must enter the exact name, otherwise, that strcmp will fail.
cin >> choice;


cin >> doesn't accept spaces as input. If you enter a space character, then everything after that space is discarded. Example: if I enter "My input", then "cin" will return "My". Use cin.getline to get over this issue. Also, I recommend you to make more space in choice. Use this:
char choice[35]; // more space here, it's "safer"
cin.getline(choice, 35); // get input, accepts spaces



And I don't understand this part:
int f = strlen (choice);
char* Name = new char[f + 1];
strncpy (Name,choice,f);
Name[f] = '\0';


this is totally useless. Why not using "choice", directly, in strcmp?
if (strcmp ((typeid(*employees[i]).name ()), choice) == 0)


Why would you want to create another pointer to char, just to copy the contents of "choice"?

EDIT: a simple program, which does exactly what you want:
#include <iostream>
#include <string>

int main()
{
        // Declare a pointer to char, allocate memory for it
        // and copy "typeid(x).name()" to it. In this case,
        // that typeid returns "char *".
	char *x = new char[10];
        if (x == NULL) 
           exit(1);
	strcpy(x, typeid(x).name());

        // The user is prompted to enter the type.
        // If you input "char *", then Equals! is printed.
        // Otherwise, Doesn't equal! is printed.
	char my_x_type[10];
	std::cout << "Enter the type: ";
	std::cin.getline(my_x_type, 10);

        // Compare.
	if (!strcmp(x, my_x_type))
		std::cout << "Equals!\n";
	else
		std::cout << "Doesn't equal!\n";

	delete [] x;
	return 0;
}


This post has been edited by sarmanu: 29 April 2010 - 01:01 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1