很抱歉,屁股代码,让我简短地解释一下。我开设了一个主要班级-工人班和两个派生班级-时薪工人,受薪工人。我做了一个虚拟函数来计算工资,不需要解释,这不是我的问题。
3 //我阅读的第一位数字决定了我将要拥有多少个工人
dave sal
史蒂夫·侯
chris sal //这三行显示工人的姓名,以及他们的工资或小时工资
10 20 10 //这3名工人的工作时间,按此顺序。
这是我想做的:根据每个工人得到的付款类型(侯或萨尔),我计算其工资,并调用虚拟函数compute_pay。输出示例:
dave 400
steve 200
克里斯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
}
}
}
}
同样,对于冗长的代码,对不起,您不必遍历所有代码,而不必遍历所有主类,更重要的是-循环。这是我的问题:假设它需要的int变量是我在最后一行读取的int hours变量,我应该在哪里确切地调用我的compute_pay函数,使其遍及所有行?另外,以后应该在哪里调用我的打印函数,以便可以看到输出?我知道这是一个愚蠢或复杂的问题,但老实说,我尽力了,我无法弄清楚:/。
在您的示例中,您对Worker
具有不同的派生,并具有自己的compute_pay
实现。使用虚拟的compute_pay
可以使您通用地使用基类,而无需每种类型都有单独的列表。
通常要使用虚拟方法,您需要一个抽象基类。这意味着基类需要虚拟方法声明(以及虚拟析构函数):
class Worker {
public:
virtual double compute_pay(int hours) = 0;
virtual ~Worker() = default;
/* all the other members go here */
};
虚拟析构函数是其中的重要部分-这意味着无论您使用哪种类型的指针,都将调用正确的析构函数。 = 0
表示它是一个pure virtual方法,该方法尚未实现,如果尝试声明基本Worker
而不是派生的方法,则该方法会中断。
派生类必须override具有该类唯一逻辑的基础虚拟方法:
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; }
};
请注意,派生类不使用virtual
,而是添加override
以表明它们应该重写虚拟基方法。
然后,您可以具有one个工作者向量:
std::vector<std::unique_ptr<Worker>> workers;
if (use_worker_a) {
workers.emplace_back(new WorkerA());
} else {
workers.emplace_back(new WorkerB());
}
注意:请尽可能使用诸如unique_ptr
之类的智能指针,而不要使用原始指针,这样就不必担心显式删除它们。
然后可以从该向量使用基本虚拟方法,而无需关心哪个指针是哪个派生类型:
double sum = 0;
for (auto& worker : workers) {
sum += worker->compute_pay(40);
}
有关计算小时数,读取文件等的所有内容,我会留给您。但这就是您有效地使用虚拟方法进行动态调度的方式。