When should I use classes

Is there any kind of rules or a guide to when should I create classes?

I am doing a school assignment in where I create a basic company workers management system.

I input the data of the workers and save them on a file, and use them all over the program.

I have some functions that I have to write like, inputWorkersDataAndSaveToFile(), readFromFileAndPrintWorkersData(), sortAndPrint, diplayWorkersWithSalariesAbove, and a few more.

So it got me wondering, should I create a class and group all these functions together since they are all related? Would it be necessary since I am going to use only one instance of the class ever?

Worth noting that I want create a vector that hold all the workers data and plan using that vector in multiple functions. One reason I started thinking about creating a class is that I am trying to avoid using global variables.

So my program would have two classes class Worker and class Manager.

Should I create a class in this scenario? Also, is there any rule of thumbs to when to create classes.
I have searched about this topic but didn't find much.

Thanks
Last edited on
When you create a class, you are creating a "type". For example, a worker class represents a worker. The member functions of a worker class should represent actions actually done by a worker. This could be a function like doWork(), checkEmail(), etc, and similarly for managers.

You should only create a class if it is more convenient and it doesn't complicate an already trivial task.
- When you call readFromFileAndPrintWorkersData(), what information is printed?
Is it something like, "hours worked", "hourly rate" , "name of worker", etc? If so, yes, you could wrap all of those characteristics into a "Worker" class. You don't necessarily need to add a bunch of functions to the class, but just organizing it together is already a good thing to do.

- How is information being passed from your other functions to your sortAndPrint functions?
It sounds like you're just using a bunch of global data? If so, this is another good reason to encapsulate and return a single Worker (or vector of Worker) objects.

e.g. your sortAndPrint function could look more like:
1
2
3
4
sortAndPrint(vector<Worker>& workers)
{
    // ....
}

You might want to just make two functions: one to sort the workers, another to print them.

As a bonus, here's one way to use the standard library's std::sort with custom classes.
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
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> 

class Worker {
  public:
    std::string name;
    double rate;
    
    bool operator<(const Worker& other)
    {
        return (rate < other.rate);
    }
};

int main()
{
    std::vector<Worker> workers {
        { "Edward",   3.41 },
        { "Samantha", 12.99 },
        { "Chingiz",  5.00 },
        { "Jurij",   -13.3 }
    };
    
    std::sort(workers.begin(), workers.end());
    
    for (const Worker& worker : workers)
    {
        std::cout << worker.name << " : " << worker.rate << '\n';   
    }
}


Jurij : -13.3
Edward : 3.41
Chingiz : 5
Samantha : 12.99
Last edited on
Doesn't the assignment give you some instructions on how to do it?
So my program would have two classes class Worker and class Manager.

Consider using a class Employee as a common base class.
This is a good question. What you appear to be trying to ask about is how to design things.

There are guidelines, but no hard rules, and the guidelines change across 'design patterns' and corporate / industrial house rules, opinions of the architect doing the design, and whatever reasons.

Would it be necessary since I am going to use only one instance of the class ever?
That is not a consideration. What you should be considering is "how does making a class here make my code better". If you can answer that it does make the code better, then you have a reason to continue. If a class does not make your code better, that happens, but you are either doing something trivial (procedural design is still valid for small simple things), or maybe mathematical where you don't need member variables just number crunching algorithms, etc. Or, if you do not understand what classes bring to the code, you may need to review what they do for you to answer it.

Worth noting that I want create a vector that hold all the workers data and plan using that vector in multiple functions. One reason I started thinking about creating a class is that I am trying to avoid using global variables.

A vector is a class, and often, it is enough to use a "C 1.0 struct" in a vector. A C struct (at least once upon a time) would only hold data, no methods or operator overloading or inheritance etc, just data elements. so struct foo {int x, double d; string s; } … vector<foo> data; If that is all you need, then its fine. If you need more, you can do more.

Avoiding global variables is a good goal. You will note that class member variables behave like globals inside the class itself (you can access without passing to each member function). So you get some of the power of globals back in a controlled environment where they do not create the risks of global scope entities.

As for your specific problem, worker and manager, what do they have in common, and what is different? There are multiple approaches.
-- they could be virtually identical, and you have a meta class named person and have person worker; and person manager; .
-- they could be distinct, and you have 2 classes.
-- they could share 50% or so of things, and still be distinct, in which case both distinct items may be a class that inherits or simply contains a common object with the shared items. (3 classes to make 2 usable ones).
--they may be very similar but have tiny differences so you use advanced class tricks like virtual methods to split out the distinct parts.
-- and so on.

for now, I recommend one of the top 3 there... and for the third one, if you do not yet know inheritance, just use has-a:
class sharedstuff{string name; ...};
class person{sharedstuff mystuff; other things;};
class manager{sharedstuff mystuff; other different things;};
person p; p.mystuff.name = "joebob"; this line is important. you will see a lot of lines like this, so the NAME of the class mystuff needs to TELL the reader what it really is, so pick the name of that class carefully. It must not be an eyesore like "mystuff" is.


Last edited on
Thanks guys for the quick replies. Really appreciate them.

@TheToaster in my case creating a class would be complicate a trivial task?

@Ganado Does it make sense to group those functions together in a class?

@Learner2 No the teacher didn't give instructions and this question on when to use classes is one that I have had for some time now. The answer will clarify a lot of things for future projects.

@jonnin thanks for taking the time and sharing this insight. I am thinking that instead of creating a class to avoid global variables I will just limit the scope with curly braces.
@jonnin thanks for taking the time and sharing this insight. I am thinking that instead of creating a class to avoid global variables I will just limit the scope with curly braces.

Do not do this. Put a namespace on them, at the very least, but you are still relying on a crutch that is bad design and is a very bad habit. There is no need for globals. None. Declare the variable inside main and pass it to the functions, if you need it to be 'nearly global'.
** I personally differentiate between constant and global here. I am fine with global constants. Constants do not vary. Constants are not, therefore, a variable. Constants should be in a namespace, but the global scope is fine.

you can make static class variables in a little class and those are globals as well.
looks like
classname::variable = value; // you do not need a variable of the class. the static item exists without a specific instance.

even putting it in a class still has risks because of the nature of globals, and its still a bad idea, but if you are determined to do it anyway, the above is probably the best way.
Last edited on
Topic archived. No new replies allowed.