how can i use array to be the object in class and call the member function?

S

surrealtrauma

i have a trouble about that:
i want to ask user to enter the employee data (employee no., name, worked
hour, etc.), but i dont know how to sort the data related to a particular
employee as a group. i want to use a array object in the class but i don't
know how..i am just learning the c++. So i dont know how to use class. in
fact, i have writen like the following:

class employee {
public:
employee();
void input_data(char, string, int, double, double);
void process_data();
void specific_emp();
void display_data_file();
private:
char emp_name[20];
string emp_no;
int hours_worked;
int no_of_employees[5];
double hourly_rate;
double salary;
};


#include <iostream>
#include <filestream>
#include "employee.h"

using namespace std;

int main ()
{
const int no_of_employees = 5;
employee employee_object[5]; /* here i dont know how to call the array
object and sort the related data as a particular employee*/
char emp_name[20];
string emp_no;
int hours_worked, no_of_employees;
double hourly_rate, salary;
int choice;

do {
cout << "please choose one of the following chioces: "<< endl;
cout << "1. Input Employee Data "
<< "2. Calculate Employee Salary"
<< "3. Enquire for a particular employee (using employee
number)"
<< "4. Transfer all input data to Employee file (empfile.dat)"
<< "5. Quit "<< endl;
cin >> choice;
} while ((choice != 1) || (choice != 2) || (choice != 3) || (choice != 4
)|| (choice != 5));

switch (choice)
{
case 1 :
employee_object[].input_data(emp_name, emp_no, hours_worked,
no_of_employees, hourly_rate, hourly_rate, salary);
break;
case 2 :
employee_object[].process_data();
break;
case 3 :
employee_object[].specific_emp();
break;
case 4 :
employee_object[].display_data_file();
break;
case 5 :
cout << "Thank you for using the employees' data program!"<<endl;
break;
}
return 0 ;
}

thank you to answer my question
 
K

Karl Heinz Buchegger

surrealtrauma said:
i have a trouble about that:
i want to ask user to enter the employee data (employee no., name, worked
hour, etc.), but i dont know how to sort the data related to a particular
employee as a group.

Actually this is fairly easy to do.

in
#include <algorithm>

there already is sort functionality available, ready to be used.
It comes in 2 flavours:

* If your class knows what it means of an object to be 'less'
then another object, you simply use

std::sort( first_element_to_sort, last_element_to_sort );

and std::sort does the rest, using < for comparing two
objects:

example:

#include <iostream>
#include <algorithm>

int main()
{
int MyData[5] = { 8, 2, 6, 3, 1 };

std::sort( &MyData[0], &MyData[5] );

for( int i = 0; i < 5; ++i )
std::cout << MyData << std::endl;
}

In this example 'int' already knows what '<' means on them.
Now if *your* objects don't know that, you can teach them:

#include <iostream>
#include <algorithm>
#include <string>

class Test
{
public:
int Points;
std::string Color;

bool operator< ( const Test& Arg ) const
{
return Color < Arg.Color;
}
};


int main()
{
Test MyData[5];

MyData[0].Points = 8;
MyData[0].Color = "Red";
MyData[1].Points = 10;
MyData[1].Color = "Green";
MyData[2].Points = 6;
MyData[2].Color = "Blue";
MyData[3].Points = 100;
MyData[3].Color = "Meganta";
MyData[4].Points = 60;
MyData[4].Color = "Cyan";

std::sort( &MyData[0], &MyData[5] );

for( int i = 0; i < 5; ++i )
std::cout << MyData.Points << " "
<< MyData.Color << std::endl;
}

Here the class 'Test' is thought what it means to be 'less' by writing
an operator< for it.

* The other possibility of using std::sort is one which takes 3 arguments:
the 2 indications of from where to where to sort, plus a predicate which
serves for the comparison
A predicate can eg. be a function, which returns true, if object 1 passed
to it is less then object 2.

Example:

#include <iostream>
#include <algorithm>
#include <string>

class Test
{
public:
int Points;
std::string Color;
};


bool IsLess( const Test& Obj1, const Test& Obj2 )
{
return Obj1.Color < Obj2.Color;
}

int main()
{
Test MyData[5];

MyData[0].Points = 8;
MyData[0].Color = "Red";
MyData[1].Points = 10;
MyData[1].Color = "Green";
MyData[2].Points = 6;
MyData[2].Color = "Blue";
MyData[3].Points = 100;
MyData[3].Color = "Meganta";
MyData[4].Points = 60;
MyData[4].Color = "Cyan";

std::sort( &MyData[0], &MyData[5], IsLess );

for( int i = 0; i < 5; ++i )
std::cout << MyData.Points << " "
<< MyData.Color << std::endl;
}
i want to use a array object in the class but i don't
know how..

What do you need that array object for in the class?
i am just learning the c++. So i dont know how to use class. in
fact, i have writen like the following:

The code you posted contains a lot of problems.
I suggest you first clean those up, before you proceed to sorting.

Don't make a typical newbie mistake: Writing to much code in one big
rush. You will end up with lots of code which will never get to compile.
Work in simple and small steps.

Start with

int main()
{
}

Then start adding thibngs. But for every thing you add: compile
it and test it. So you could eg start with adding an Employee
class:

class employee {
public:

private:
char emp_name[20]; // any reason why you don't use a std::string?
string emp_no;
int hours_worked;
double hourly_rate;
double salary;
};

int main()
{
}

compile it. If it does, fine. If not: fix any errors.
Time has come to create the first employee. So you add
another thing:

class employee {
public:
employee();
void Display();

private:
char emp_name[20]; // any reason why you don't use a std::string?
string emp_no;
int hours_worked;
double hourly_rate;
double salary;
};

employee::employee()
{
emp_name[0] = '\0';
emp_no = "1234";
hours_worked = 0;
salary = 5;
};

void employee::Display()
{
cout << "Hi, I am " << emp_name << "\n";
cout << "My number is " << emp_no << "\n";
cout << "I have worked for " << hours_worked << " hours\n";
cout << "I earn " << salary << " per hour\n";
}

int main()
{
employee Bob;

Bob.Display();
}

compile it, test it. Does it do what you want? If yes
continue and add the next thing (could eg. be some functions
to enter data into the Bob object), if not, fix any errors
and continue with this step until the program does what you
want it to do in this step.

Add next thing.

And so on, and so on.
Don't write your program in one big rush, develop in small steps
instead. This way it is much easier to fix bugs, since you know that
any bugs are related to the things you added in the last step.
 
M

Mike Wahler

Karl Heinz Buchegger said:
And so on, and so on.
Don't write your program in one big rush, develop in small steps
instead. This way it is much easier to fix bugs, since you know that
any bugs are related to the things you added in the last step.

I'd like to add to Karl's (usual) excellent advice:

When you write, compile, and test your code incrementally
like this, often you'll find yourself writing functions which
are of a 'generic' nature, and can be used in other programs.
The plus is that you'd be including an already tested and debugged
function, and can concentrate your efforts on the new stuff.
And to make it even easier to re-use these functions, put them
in their own separate files, then it's easy to add them to
a new 'project'.


-Mike
 
S

surrealtrauma

Thank for your help.

// any reason why you don't use a std::string?
since I havn't learn about std::string.

i have very poor skill with using c++, i am just doing the hw.But I dont
know how to do. In fact, i am asked to convert the "struct" to a "class",
the following is the code that teacher gives to me :

// This program is used to input data for employees and process the data
to obtain
// the salary of employees and the average hours worked by all employees.
Finally,
// all the information about the employees will be displayed together with
the
// average hours worked by all employees. Please pay attention to getline
function
// and ignore function for string operations which will be discussed in
details in chapter 11.

#include<iostream>
#include<cstring>
using namespace std;
const int no_of_employees = 5; // no. of employees in company

struct employee_record // create an employee record
{
char emp_name[20]; // a text string of 19 characters plus one null
character
int hours_worked; // no. of hours worked by a particular
employee
double hourly_rate; // hourly rate of a particular employee
double salary; // salary obtained by multiplying hourly rate
and hours_worked
};

// input employee data
void input_data(employee_record employee_info[]);

// calculate the employees' salary and average hours worked among all
employees
void process_data(employee_record employee_info[], double
&average_hours_worked);

// display all employees' information
void display_data(employee_record employee_info[], double
average_hours_worked);

int main()
{

employee_record employee_info[no_of_employees];
double average_hours_worked;
input_data(employee_info);
process_data(employee_info, average_hours_worked);
display_data(employee_info, average_hours_worked);
return 0;
}


// input employee data such as name, hours worked and hourly rate
// There are no validation steps for data input, try to validate the data
input
void input_data(employee_record employee_info[])
{
//int j;
//char text[80];
for (int i=0; i<no_of_employees; i++)
{
cout << "Employee " << i+1 << " name : ";
// getline used to read characters until size of 19 or RETURN key is
pressed below size of 19. Store them in emp_name string
cin.getline (employee_info.emp_name, 20);
cout << "Hours worked: ";
cin >> employee_info.hours_worked;
cout << "Hourly rate: ";
cin >> employee_info.hourly_rate;
cin.ignore(); // used to skip the newline
character; input problems occur without using this statement
}
}

// calculate the employees' salary and average hours worked among all
employees
void process_data(employee_record employee_info[], double
&average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to calculate
salary for all employees and
{ // sum up the hours worked for all employees
employee_info.salary = employee_info.hours_worked *
employee_info.hourly_rate;
sum = sum + employee_info.hours_worked;
}
average_hours_worked = sum / no_of_employees; // calculate the average
hours worked by employees
}

// display information of all employees and finally display the average
hours worked among all employees
void display_data(employee_record employee_info[], double
average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to produce
all employees' information
{
cout << endl;
cout << "Employee Name: " << employee_info.emp_name << endl;
cout << "Hours Worked: " << employee_info.hours_worked << endl;
cout << "Employee Salary: " << employee_info.salary << endl;
}
cout << endl;
cout << "Average hours worked for " << no_of_employees << " employees: "
<< average_hours_worked << endl;
}

According to his code, i try to convert. i get confuse that is
"employee_info.salary" only can be use in struct or it can also be used
in class...i get lose
 
M

Mike Wahler

surrealtrauma said:
Thank for your help.

// any reason why you don't use a std::string?
since I havn't learn about std::string.

If you read up about it, you should realize that it is
much easier to use, and less error-prone. But of course
if your instructor has disallowed them, you don't have
much choice.
i have very poor skill with using c++, i am just doing the hw.But I dont
know how to do. In fact, i am asked to convert the "struct" to a "class",
the following is the code that teacher gives to me :

[snip code]
According to his code, i try to convert. i get confuse that is
"employee_info.salary" only can be use in struct or it can also be used
in class...i get lose


Good 'class' and 'struct' mean essentially the same thing
(but not exactly.) The difference is in 'default' access.

In a 'struct', all members are publicly accessible (that is, they
can be referred to by code 'outside' the class' member functions).
Selected members can be made externally inaccessible with the
'private' keyword.

In a 'class', by default, only member functions can access the
class's members (both data and functions). 'public' access must
be explicitly specified.

So, in summary, a 'struct' has a default access of 'public', and
a 'class', one of 'private':

Maybe this example will help:

#include <iostream>

struct s
{
/* everything will be 'public' until otherwise specified */
int i;
void foo()
{
std::cout << j << '\n';
}

private:
/* every following member will be 'private' until otherwise specified */
int j;
};

class c
{
/* everything will be 'private' until otherwise specified */
int k;
void foo()
{
std::cout << k << '\n';
}

public:
/* every following member will be 'public' until otherwise specified */
int m;
c(int arg) : k(arg)
{
}

void boo()
{
foo();
}
};

int main()
{
/* struct: */

s a_struct;
a_struct.i = 42; /* OK, 's::i' is public */
a_struct.j = 99; /* ERROR, 's::j' is private */
a_struct.foo(); /* OK, 's::foo' is public */
/* (and it can access the 'private' */
/* member 'j' because it's a member of */
/* the same class) */


/* class: */

c a_class(25); /* invokes the (public) constructor */
/* which initializes the (private) */
/* member 'k' */

a_class.k = 0; /* ERROR 'c::k' is private */
a_class.m = 5; /* OK, 'c::m' is public */
a_class.foo(); /* ERROR, 'c::foo' is private */
a_class.boo(); /* OK, 'c::boo' is public */

return 0;
}

There's another access keyword, 'protected', used with inheritance,
which I left out in the interest of a simple explanation.

Finally, it's generally recommended that data members be 'private',
and only manipulated by member functions. This helps prevent
inadvertent manipulation by 'outside' code. Also, member functions
which only do stuff 'internal' to the class (i.e. are only invoked
from other member functions of the same class) should also be
'private'. The 'public' functions are commonly called the 'public'
interface of the class. These are what outside code uses to manipulate
the object. All this helps to enforce the class' 'rules' and keep
its objects' integrity.

HTH,
-Mike
 
M

Mike Wahler

Mike Wahler said:
its objects' integrity.

I meant to add that you can prevent the necessity of depending
upon 'default' access with either 'struct' or 'class' by always
using keywords to explicitly specify access. Then there's no
effective difference between 'struct' and 'class' except the
spelling of the keywords(*). But it is a good idea that you
do remember these rules, for when you read others' code, which
likely will not do this.

struct s
{
private:
int i;
public:
s(int arg) i(arg)
{
}
};

class c
{
private: /* redundant but harmless */
int j;
public:
c(int arg) j(arg)
{
}
};

Objects of types 's' and 'c' will have identical
behavior.

However, I suspect that your instructor means for you
to use 'private' appropriately in order to enforce
object integrity and consistency. But you'd have
to check with him/her to be sure.


HTH,
-Mike
(*) The inheritance specification for 'struct' and 'class' also
has a different default: 'struct', with public inheritance, 'class'
with 'private' inheritance, again overridable with these keywords.
But it seems you're not into inheritance yet.
 
K

Karl Heinz Buchegger

surrealtrauma said:
Thank for your help.

// any reason why you don't use a std::string?
since I havn't learn about std::string.

Funny, you already have used it !
The second parameter to 'input_data' is of type string and so
is the member variable 'emp_no'
i have very poor skill with using c++, i am just doing the hw.

No problem. We all started sometimes.

[snip code]

WHen I compare your code with your teachers code then I see a pattern:
You simply moved all functions in the class. Well, that's not entirely wrong,
but in your case you made an oversight:

An object of class employee is responsible for *one* employee.
The functions your teacher gave you however deal with a whole
array of employees.

Now when you move such a function into the class, you should stick
with: deals with just one object. That also means that you still will
have those stand alone (non class) functions that have to deal with
the whole array of objects. But this time the functionality is balanced
differently.

Example:

Your teacher gave you:

// display information of all employees and finally display the average
// hours worked among all employees
void display_data(employee_record employee_info[], double average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to produce
// all employees' information
{
cout << endl;
cout << "Employee Name: " << employee_info.emp_name << endl;
cout << "Hours Worked: " << employee_info.hours_worked << endl;
cout << "Employee Salary: " << employee_info.salary << endl;
}
cout << endl;
cout << "Average hours worked for " << no_of_employees << " employees: "
<< average_hours_worked << endl;
}

You now need to analyze this function and ask youself a question: Which of the above
is really the responsibility of one single employee object, and which of the above
is just there because that function deals with a whole array of objects.

If you do this, it turns out, that outputting the employee data (such as name, hours worked,
salary) can be seen as the reponsibility of one employee object. It is like you give
an order to one employee: 'Hey, Bob. Give me your data!'. Thus you will want to add
a function to your class, that does exactly that: output the employees data. You will
use that by eg.

void display_data(employee_record employee_info[], double average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to produce
// all employees' information
{
employee_info.display_data();
}
cout << endl;
cout << "Average hours worked for " << no_of_employees << " employees: "
<< average_hours_worked << endl;
}

See. The above function no longer needs to know, that an employee has a name, knows how
many hours he/she has worked etc. The function simply delegates to the amployee object
itself to output its data. And it is up to the employee object to know what data can
be output:

class employee
{
....

void display_data();

....
};

void employee::display_data()
{
cout << "Employee Name: " << emp_name << endl;
cout << "Hours Worked: " << hours_worked << endl;
cout << "Employee Salary: " << salary << endl;
}

This is where object orientation kicks in. Each object is reponsible for itself.
It is not the job of the stand alone display_data function, to know that an employee
has a name, a number and a salary. It just tells the object to output itself.

That doesn't mean that it may not be a good idea to have employee member functions
to allow for getting at the name, salary and so on. The problem is this: Now the
functionality of which data members get output has moved into the employee class.
That may be a good thing. But who is telling you, that you want exactly that information
in the output? For a different purpose you might want a different output, but the
employee object cannot know this. It is out of its scope to know this, because it
may depent entirely on what type of listing you are creating: An output for just
having all employees with their employee number looks different from a listing which
is used to pay those employees.

So what I am trying to get at is: When you move functionality around, you need to think
about which functionality belongs where. Eg. a function that calculates the total salary
based on hours worked and the hourly rate is definitily a member of the employee
class. So make it one:

class employee
{
....

void CalculateSalery();
void display_data();

....
};

void employee::CalculateSalery()
{
salary = hours_worked * hourly_rate;
}

and you use that function eg. in

// calculate the employees' salary and average hours worked among all
// employees
void process_data(employee_record employee_info[], double &average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to calculate
// salary for all employees and
{
employee_info.CalulateSalary();
sum = sum + employee_info.hours_worked;
}

average_hours_worked = sum / no_of_employees; // calculate the average
// hours worked by employees
}

Again: Note the slight shift in reponsibility. It is no longer the job of
this function process_data to calulate the salary for each employee. Instead
this functionality is shifted to the employee object itself. There might
be different ways to calculate that salary, there may be addons, different taxes
to pay etc. But it is not the job if this function to account for that - the
employee itself should do that.
What about the hours worked among all employees. Can a single employee know how
to do that? No. A single employee object knows about, well, a single employee
object. But to calculate that average, *all* employees need to participate. Thus
this functionality cannot be shifted into the employee class. It is simply not
its responsibility to calculate that average. Thus this functionality will stay
in function process_data(). But of course this function will need some ways to
get at the data which allows it to calculate that average. In particular it
will need a function which allows it to ask each employee for the hours he/she
worked:

// calculate the employees' salary and average hours worked among all
// employees
void process_data(employee_record employee_info[], double &average_hours_worked)
{
double sum = 0;
for (int i=0; i<no_of_employees; i++) // loop used to calculate
// salary for all employees and
{
employee_info.CalulateSalary();
sum = sum + employee_info.GetHoursWorked();
}

average_hours_worked = sum / no_of_employees; // calculate the average
// hours worked by employees
}

And employee, of course will need to implement that function:

class employee
{
....

int GetHoursWorked();
void CalculateSalery();
void display_data();

....
};

coid employee::GetHoursWorked()
{
return hours_worked;
}

void employee::CalculateSalery()
{
salary = hours_worked * hourly_rate;
}

Now, what is so important about that shift of functionality?
Well. We have freed the function process_data of the knowlegde of how
and where the information 'hours_worked' is stored. It simply doesn't
care any longer. All this function does is ask the employee object:
"Hey, Buddy. How many hours have you worked?" And the employee object
responds with the correct figure. All that is important for process_data
is to get that number. It is no longer important for process_data how
the imployee object came up with that number. The employee object could,
have looked it up in a data base, it could have calculated that number,
it could have consulted some registering clock to come up with that number,
etc. All of that is no longer important to process_data. It asks the
employee object for that number, and it gets it from the employee object.

That is an important point in object oriented programming: To put
functionality where it belongs in order to free the rest of the
program to know the details how a specific functionality works.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top