我最初在CodeReview上问了这个问题。由于那里的接待不佳(完全是我的错),我认为这是问的正确地方。我要在此处复制我在那儿问过的完全相同的问题(进行一些小的修改)。
我的目标是尽可能使用STL功能以C ++编写CPU调度模拟器。到目前为止,我只编写了FCFS的代码,还没有提供任何输入方法。
对我来说最突出的是流程类的定义。我设计程序的方式,封装很差。从我目前的情况来看,我只有两种解决方案:
将所有数据成员设为私有。为PID,到达时间和突发时间提供访问器,并为其余部分提供变量器。但是,我担心这会使我的代码肿,而且使用mutator只会破坏封装。
使FCFS()
,displayResult()
和我添加的friend
类的process
的任何其他算法。这使我可以在一定程度上控制封装,因此我很喜欢这种封装。
我试图做的另一件事是使PID,到达时间和突发时间变量const
公开。这允许算法读取它们的值,但不能修改它们。但是,由于const
成员不是默认可分配的,因此无法编译代码。
我想就如何解决上述问题以及如何更有效地使用STL使代码更具表现力提出建议。
#include <iostream>
#include <vector>
#include <algorithm>
#include <limits>
constexpr int notYetComputed = std::numeric_limits<unsigned int>::max();
struct process
{
unsigned int m_procId;
unsigned int m_arrivalTime;
unsigned int m_burstTime;
unsigned int m_responseTime;
unsigned int m_completionTime;
unsigned int m_turnaroundTime;
unsigned int m_waitingTime;
process(unsigned int pid, unsigned int at, unsigned int bt)
: m_procId {pid}, m_arrivalTime {at}, m_burstTime {bt}
{
m_waitingTime = m_turnaroundTime = m_completionTime = m_responseTime = notYetComputed;
}
};
void displayResult(const std::vector<process>& procs)
{
for(auto& x : procs)
std::cout << "PID: " << x.m_procId << ", "
<< "Waiting Time: " << x.m_waitingTime << ", "
<< "Turnaround Time: " << x.m_turnaroundTime << ", "
<< "Response Time: " << x.m_responseTime << ", "
<< "Completion Time: " << x.m_completionTime << "\n";
}
void FCFS(std::vector<process>& procList)
{
//Sort based on arrival order. Use PID in case of same arrival time.
auto arrivalOrder = [] (const process& p1, const process& p2) {
if(p1.m_arrivalTime < p2.m_arrivalTime) return true;
if(p1.m_arrivalTime == p2.m_arrivalTime) return (p1.m_procId < p2.m_procId);
return false;
};
std::sort(procList.begin(), procList.end(), arrivalOrder);
unsigned int clock {0};
auto computeResult = [&clock] (process& pr) {
pr.m_responseTime = clock - pr.m_arrivalTime;
pr.m_waitingTime = (pr.m_turnaroundTime =
(pr.m_completionTime = (clock += pr.m_burstTime)) - pr.m_arrivalTime)
- pr.m_burstTime;
};
std::for_each(procList.begin(), procList.end(), computeResult);
}
int main()
{
std::vector<process> procs {{0,0,5}, {1,1,3}, {2,2,8}, {3,3,6}};
FCFS(procs);
//Sort based on PID before showing result
std::sort(procs.begin(), procs.end(),
[](const process& p1, const process& p2) {
return p1.m_procId < p2.m_procId;
});
displayResult(procs);
}
更新:
我打算将来增加更多的调度算法。所以我更喜欢Jarod42的思路。我真的不能将特定于算法的代码作为
process
类的一部分。 最佳答案
您的流程类同时包含输入和输出成员。
我将它们分开(我使用的名称可能应该改进)以明确说明流程(并且我们可以摆脱notYetComputed
,这似乎对我来说是一个hack):
struct process_input
{
unsigned int m_procId;
unsigned int m_arrivalTime;
unsigned int m_burstTime;
};
struct process_ouput
{
unsigned int m_responseTime;
unsigned int m_completionTime;
unsigned int m_turnaroundTime;
unsigned int m_waitingTime;
};
struct process
{
process_input m_input;
process_output m_output;
};
FCFS
将显示流,因此std::vector<process> FCFS(std::vector<process_input> inputs)
经过一些样式更改,它变为:
std::vector<process> FCFS(std::vector<process_input> inputs)
{
// Sort based on arrival order. Use PID in case of same arrival time.
auto proj = [](const process_input& p){ return std::tie(p.m_arrivalTime, p.m_procId); };
auto compare = [&] (const process& lhs, const process& rhs) {
return proj(lhs) < proj(rhs);
};
std::sort(inputs.begin(), inputs.end(), compare);
std::vector<process> res;
res.reserve(inputs.size());
unsigned int clock {0};
auto computeOutput = [] (const process_input& pr, unsigned int& clock) {
process_ouput res;
res.m_responseTime = clock - pr.m_arrivalTime;
clock += pr.m_burstTime;
res.m_completionTime = clock;
res.m_turnaroundTime = res.m_completionTime - pr.m_arrivalTime;
res.m_waitingTime = res.m_turnaroundTime - pr.m_burstTime;
return res;
};
for (auto& input : inputs) {
res.push_back({input, computeOutput(input, clock)});
}
return res;
}
将
main
更改为:int main()
{
std::vector<process> inputs {{0,0,5}, {1,1,3}, {2,2,8}, {3,3,6}};
auto procs = FCFS(inputs);
//Sort based on PID before showing result
std::sort(procs.begin(), procs.end(),
[](const process& p1, const process& p2) {
return p1.m_input.m_procId < p2.m_input.m_procId;
});
displayResult(procs);
}
现在我们要保留哪些保证?
process_input
是没有内部约束的简单数据。process_output
是简单数据,似乎也没有内部约束。process
在输入和输出之间应该具有一致性:因此,不能对其成员进行非const访问。// const member might be enough in that case,
// but I prefer to avoid const members
// which make class harder to use (not movable, not assignable, ....)
// so only const getters
struct process
{
public:
const process_input& input() const { return m_input;
const process_output& output() const { return m_outnput; }
private:
process_input m_input;
process_output m_output;
};
作为getter的替代或补充,您可以在此处添加
Display
方法。关于c++ - 如何重新设计/修复此程序以允许封装?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57240661/