0

Given an abstract class called Job and other classes that inherit it like Teacher, Worker ,etc...

I want those classes to inherit something like a static variable -I'm saying like since it's not allowed to inherit static according to what I read- for Job (Like Salary) with different values for each class, how may I do that?

Until now, in the c'tor for Teacher I have created a local variable for each object called salary such that it's equal to 100, but that doesn't seem smart since all teachers have the same salary according to what I'm working on.


For example:

class Job{ int salary; std::string tag; public: Job(int salary,std::string tag;) : salary(salary), tag(tag) {} }; class Teacher: public Job{ public: Teacher(std::string tag) : Job(100,tag){} }; class Worker: public Job{ Worker(std::string tag) : Job(200,tag){} }; 

every worker has salary=100 but I want this to be related to the class worker and not for each object. (I can define this as static for each class but again it doesn't seem smart to declare the same static value in 100 classes the inherit a one which has that static value)

11
  • Can you maybe add some code for your current approach, and how you would like it to work? Commented Jun 27, 2020 at 15:17
  • 1
    @MikaelH working on that Commented Jun 27, 2020 at 15:18
  • 1
    Until now, in the c'tor for Teacher I have created a local variable for each object called salary such that it's equal to 100, but that doesn't seem smart since all teachers have the same salary according to what I'm working on. On the contrary, it's exactly right. There is nothing wrong with the code you posted (and, one day, you will be able to give individual teachers a pay rise :) Commented Jun 27, 2020 at 15:28
  • 1
    @PaulSanders why every worker should have a variable called Salary with a value of 200 while it's sharable for All workers Commented Jun 27, 2020 at 15:30
  • 1
    @AdrianMole Or those who prohibit the use of the STL... Commented Jun 27, 2020 at 15:34

3 Answers 3

1

I hesitate to post this answer, because I think the code as posted is just fine, but if you really want to eliminate the salary variable, then you can do this:

class Job { ... virtual int GetSalary () = 0; }; class Teacher : public Job { ... int GetSalary () override { return 100; } }; class Worker : public Job { ... int GetSalary () override { return 200; } }; 

A similar scheme can be used to get rid of tag (and, for that, this approach might actually be warranted).

Sign up to request clarification or add additional context in comments.

Comments

1

You could also make use of templates, they are evaluated at compile-time so you won't have performance overhead:

template <int Salary> class Job{ std::string tag; public: static const int salary = Salary; Job(std::string tag) : tag(std::move(tag)) { } }; class Teacher: public Job<100>{ public: Teacher(std::string tag) : Job<100>(std::move(tag)) { } }; class Worker: public Job<200>{ Worker(std::string tag) : Job<200>(std::move(tag)) { } }; 

and you can just get the salary from plain old Teacher::salary, Worker::salary, Job<N>::salary, etc.

3 Comments

What is std::move why not tag(tag)?
@BigSur tag(tag) creates a useless copy to the tag argument inside of the constructor. std::move converts the argument to an rvalue reference so that its value can literally be moved to another location (here, it is a member variable) and avoid any copy. In the process, the value in the original location (i.e, the argument tag) becomes invalidated.
With this approach you no longer get a common base class, which seems to be one of the goals of OP with the initial code.
0

I am not sure if this is more software design. Anyway, I will give you feedback for the current design and what you could do (still using public inheritance).

The code you currently have is fine. It is flexible, since you can actually set a specific salary per object.

But, of course, you are paying for the flexibility - for each object, you will have a maybe unnecessary member, since it should already be known by the type.

If you want the flexibility to have classes with same salary, and classes with specialized salaries, you can extend your hierarchy a bit:

class IJob{ public: virtual double getSalary() = 0; }; // Teachers always have the same salary class Teacher: public IJob{ static constexpr double salary = 200; // named constant, not strictly necessary. But it can make it more readable. public: double getSalary virtual() { return salary; } }; // Worker always have the same salary class Worker : public IJob{ static constexpr double salary = 100; public: double getSalary virtual() { return salary; } }; // A base class for workers having different salaries class SalarizedJob : public IJob double salary; public: SalarizedJob(double salary) : salary(salary) {} double getSalary() override { return salary; }; }; // Greedy bankers always want more salary than their coworker class Banker : public SalarizedJob { public: Banker(double salary) : SalarizedJob(salary) {} }; 

Comments