简体   繁体   English

需要关于我应该在哪里调用虚拟函数的帮助

[英]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.我做了一个计算工资的虚函数,不用解释了,这不是我的问题。

I read an input, here's an example:我读了一个输入,这是一个例子:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM