[英]Need help on where i should call a virtual function
Sorry for the long ass code, let me explain briefly.抱歉,代码太长,让我简单解释一下。 I made a main class - Worker and two derived classes - hourlyworker, salaried worker.
我做了一个主类 - Worker 和两个派生类 - 小时工,受薪工人。 I made a virtual function that calculates a salary, no need to explain it, that's not my question.
我做了一个计算工资的虚函数,不用解释了,这不是我的问题。
3 //first digit i read determines how many workers i'm going to have 3 //我读取的第一个数字决定了我将拥有多少工人
dave sal戴夫萨尔
steve hou史蒂夫侯
chris sal //those 3 lines show names of workers and if they are paid with salary or hourly chris sal //这 3 行显示工人的姓名,以及他们是按工资还是按小时支付
10 20 10 //the working hours of those 3 workers, in that order. 10 20 10 //这3个工人的工作时间,按顺序排列。
Here's what i want to do: Depending on the type of payment each worker gets (hou or sal) i calculate his salary, calling the virtual function compute_pay.这就是我想要做的:根据每个工人获得的付款类型(hou 或 sal),我计算他的薪水,调用虚拟函数 compute_pay。 Example output:
示例输出:
dave 400戴夫 400
steve 200史蒂夫 200
chris 400. Here's my code:克里斯 400。这是我的代码:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Worker {
public:
void print();
protected:
string name;
string type;
};
class HourlyWorker : public Worker {
public:
HourlyWorker(string n) {
name = n;
}
virtual double compute_pay(int hours) {
double payment = 10;
if (hours <= 40) {
return hours * payment;
}
else {
return (40 * payment) + ((hours - 40) * payment * 1.5);
}
}
void print(int a) {
cout << name << " " << a << "\n";
}
private:
string name;
string type;
}
class SalariedWorker : public Worker{
public:
SalariedWorker(string n) {
name = n;
}
virtual double compute_pay(int hours) {
hours = 40;
int payment = 10;
return payment * hours;
}
void print(int a) {
cout << name << " " << a << "\n";
}
private:
string name;
string type;
};
void print(vector<SalariedWorker*> sal, int a)
{
for (int i = 0; i < sal.size(); i++)
sal[i]->print(a);
}
void print(vector<HourlyWorker*> sal, int a)
{
for (int i = 0; i < sal.size(); i++)
sal[i]->print(a);
}
int main()
{
vector<SalariedWorker*> sal;
vector<HourlyWorker*> hour;
int first; //first digit
int hours; //hours of each worker
string name; //name or worker
string type; //sal or hou
cout << "go" << "\n";
cin >> first;
for (int i = 0; i < first+1; i++) {
if (i < first) {
cin >> name >> type;
if (type == "sal") {
SalariedWorker* sall = new SalariedWorker(name);
sal.push_back(sall); //If a worker is "sal" i write into the HourlyWorker vector
}
else if (type == "hou") {
HourlyWorker* hourr = new HourlyWorker(name);
hour.push_back(hourr);
} //If a worker is "hou" i write into the HourlyWorker vector
else {
cout << "Wrong input" << "\n";
return 1;
}
}
else { //This triggers when we reach the last line. It triggers only once
for (int z = 0; z < first; z++) {
cin >> hours; //reading the last line
}
}
}
}
Again, sorry for the long code, you don't have to go trough all of it, just the main class, and more importantly - the loop.再次抱歉,代码太长,您不必遍历所有内容,只需遍历主类,更重要的是 - 循环。 Here's my question: where exactly should i call my compute_pay function so that it goes thorugh all the lines, assuming the int variable it requiers is the int hours variable i read at the last line?
这是我的问题:我到底应该在哪里调用我的 compute_pay 函数,以便它遍历所有行,假设它需要的 int 变量是我在最后一行读取的 int hours 变量? Also, where should i call my print function afterwards so i can see my output?
另外,之后我应该在哪里调用我的打印功能,以便我可以看到我的输出? I know it's a stupid or complicated question, but i honestly tried my best and I cannot figure it out :/.
我知道这是一个愚蠢或复杂的问题,但老实说我已经尽力了,但我无法弄清楚:/。
In your example, you have different derivations of Worker
with their own implementation of compute_pay
.在您的示例中,您有不同的
Worker
派生及其自己的compute_pay
实现。 What having a virtual compute_pay
does, is let you use the base class generically, without needing to have separate lists of each type.拥有一个虚拟的
compute_pay
作用是让您通用地使用基类,而无需具有每种类型的单独列表。
To generically use virtual methods, you need an abstract base class.要通用地使用虚拟方法,您需要一个抽象基类。 This means that the base class needs a virtual method declaration (as well as a virtual destructor):
这意味着基类需要一个虚方法声明(以及一个虚析构函数):
class Worker {
public:
virtual double compute_pay(int hours) = 0;
virtual ~Worker() = default;
/* all the other members go here */
};
The virtual destructor is an important part of this - it means that the correct destructor will be called no matter what type of pointer you're using.虚拟析构函数是其中的一个重要部分——这意味着无论您使用什么类型的指针,都会调用正确的析构函数。 The
= 0
means it's a pure virtual method, which is not implemented and will break if you try and declare a base Worker
instead of a derived one. = 0
表示它是一个纯虚方法,它没有实现,如果你尝试声明一个基Worker
而不是派生的,它就会中断。
Derived classes must override that base virtual method with the logic unique to that class:派生类必须使用该类独有的逻辑覆盖该基虚拟方法:
class WorkerA {
public:
double compute_pay(int hours) override { /* whatever */ return 42.0; }
};
class WorkerB {
public:
double compute_pay(int hours) override { /* whatever */ return 25.0; }
};
Note that the derived classes don't use virtual
, but instead add override
to communicate that they're supposed to override a virtual base method.请注意,派生类不使用
virtual
,而是添加override
来传达它们应该覆盖虚拟基方法。
Then, you can have one vector of workers:然后,您可以拥有一个工人向量:
std::vector<std::unique_ptr<Worker>> workers;
if (use_worker_a) {
workers.emplace_back(new WorkerA());
} else {
workers.emplace_back(new WorkerB());
}
Note: use a smart pointer such as unique_ptr
instead of raw pointers whenever you can so you don't have to worry about explicitly deleting them.注意:尽可能使用诸如
unique_ptr
类的智能指针而不是原始指针,这样您就不必担心显式删除它们。
The base virtual methods can then be used from that vector, without caring which pointer is which derived type:然后可以从该向量使用基本虚拟方法,而无需关心哪个指针是哪个派生类型:
double sum = 0;
for (auto& worker : workers) {
sum += worker->compute_pay(40);
}
All the stuff about computing the number of hours, reading from a file, etc, I'll leave that to you.关于计算小时数、读取文件等的所有内容,我将留给您。 But that's how you use virtual methods for dynamic dispatch effectively.
但这就是您如何有效地使用虚拟方法进行动态调度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.