存储与任务关联的名称列表

Storing list of names associated with tasks

本文关键字:列表 关联 任务 存储      更新时间:2023-10-16

所以我做了这个任务系统,或者我正在尝试做它,这样如果有人做了七个以上的任务,下一个人必须做七个。

双打(Bodine,Finn,Tycho)是人。现在我不知道我是否正确使用了它,(如果它们需要是双精度)以及我如何在这行代码中使用它们:

if (taskNumbers == 7)
{
std::cout << "It's " + /*what to do here? */ + "time!";

我想要的是,如果任务数大于 7,而 Bodine 已经完成了 7 个任务,它会说"这是他的时间!

#include <iostream>
using namespace std;
double Bodine;
double Finn;
double Tycho;
bool tasksDone = true;
int taskNumbers = 0;
int main()
{
if (taskNumbers > 7)
{
std::cout << "It's " + /*what to do here? */ + "time!";
return 1;
}
}

这是我的第一个项目之一(im 13,所以是的...我只需要知道如何使用下一个变量!

好吧,你并没有真正跟踪轮到谁了。此外,double不是适合这里工作的工具。我会做这样的事情:

std::vector<std::string> users = { "Bodine", "Finn", "Tycho" };
int currentUser = 0;

现在我们有一个名字列表以及一个计数器,上面写着轮到谁了。0是第一人称,1是第二人称,2是第三人称。然后我们需要逻辑来推进该计数器:

void advanceUser() {
if (++currentUser >= users.size()) {
currentUser = 0;
}
}

这会增加currentUser,当它大于人数时,它会循环回0,所以人们正确地轮流。

接下来关于任务逻辑,我会建议这样的东西:

int tasksDone = 0;
void incrementTasksDone() {
if (++tasksDone >= 7) {
advanceUser();
std::cout << "It's " + users[currentUser] +"'s time!" << std::endl;
tasksDone = 0;
}
}

在这里,我们有一个计数器,可以跟踪任务量,当它命中时7,它会将其设置回0,并在调用advanceUser设置该权限后宣布轮到下一个用户了。

然后,您可以根据需要调用incrementTasksDone,例如我像这样测试它:

int main()
{
for (int i = 0; i < 100; i++) {
incrementTasksDone();
}
}

例如,这将完成100个任务,因此轮次将在此过程中更改14次,并且每次都会打印消息。

此外,若要运行此示例,请务必添加以下内容:

#include <vector>
#include <string>
#include <iostream>

您好,欢迎来到C++。许多人会说C++对于初学者来说是一种糟糕的语言选择。好吧,我很久以前就开始C++自己,直到今天我还在学习。我是 100% 自学成才的,我没有今天人们在互联网上可用的大量信息以及可用的现代格式方面的优势。当我刚开始学习C++时,互联网正处于蓬勃发展的阶段;但当时大多数网站几乎都是纯文本,即使是简单的图片或图形也需要一段时间才能加载到屏幕上,因为这是在Dial Up时代。今天,刚起步的人拥有这个网站、其他类似网站甚至 youtube 视频的优势。但是,我仍然喜欢尽我所能提供帮助,因为它不仅可以帮助您,而且还可以帮助我改进我已经学到的东西。C++多年来一直在发展,所以我在这里要做的是向你演示一个小应用程序,我相信它模仿了你描述的你正在尝试做的事情的行为。其中一些技术有点先进,特别是对于初学者,但我认为新手尽早学习这些概念是一个很好的选择。


  • Storage Types & Lifetime-C++基本上有4种主要的存储类型:AutomaticDynamicStaticThread。我主要关注前 3 个。

    • Automatic:它具有声明它的作用域的生存期,一旦该作用域从其右大括号退出,它将自动销毁}
    • Dynamic:由指针表示但用new声明的内存,并且必须具有匹配的delete,或分别new[]delete[]数组。它们的寿命可以超过其声明的范围。它们将一直存在,直到调用其匹配的删除。如果没有发生匹配的删除,这会导致内存泄漏,无效指针,悬空指针和引用以及未定义的行为。使用raw-pointers时需要特别注意;建议使用containerssmart pointers.
    • Static:这些通常位于global命名空间和/或global filespace中。如果在main.cpp中声明了static,它将具有应用程序的生存期和整个程序的范围。如果它们在其他cpp文件中声明,它们将具有该文件的范围,除非它们在某个header文件中声明,则它们将具有其他翻译单元包含该标头的范围。它们类似于Automatic,因为它们将自动销毁,但它们的不同之处在于它们只初始化一次,保持它们的状态,并且您只能拥有它们的单个实例。
    • 有关不同类型的存储分类的演示,请参阅我之前对此问答的回答。
  • Classes and Inheritance:- (我不会涉及Polymorphism)。

    • Classes:
      • ClassesStructs是用户定义的数据类型。
      • 两者之间的区别在于默认访问
      • 默认情况下:StructsPublic MembersClassesPrivate Members
      • ClassStruct的成员可以是任何内置类型、指向类型的指针、其他用户定义的数据类型以及方法或函数。
      • Member Variables可以是任何StorageTypeAutomaticDynamicStaticThread,但是,成员函数通常是Automatic的,但可以Static。如果您有member variable则必须在Class'sDeclaration之外initialized它才能解决它symbols
      • 默认情况下,它们具有ConstructorsDestructors,但可以创建自己的自定义ConstructorDestructor。你通常会看到人们用他们的简称提到他们:分别为ctordtor
      • 一个类可以从另一个类继承。
    • Inheritance:
      • 你有BaseSuperClasses,你有DerivedChildClasses
      • 当从BaseInheriting时,如果Base类的ctorPublic,这意味着你可以创建一个同时具有BaseDerivedClasses的对象。有时你想要这种设计,但有时你不需要。
      • 如果您不希望用户能够创建BaseClass的实例,但能够创建Derived Class的实例,那么您需要做的就是确保1st它的ctorProtected。如果您将其声明Private,那么即使是您的DerivedClasses也无法访问它,因此无法声明它们。*第二 您要确保您的Destructors-dtorsVirtual;否则,您将遇到销毁类的顺序问题。
      • BaseClass可以有VirtualMember Functions,这意味着所有DerivedClasses都必须ImplementFunction
      • BaseClass可以具有Purely VirtualMember Functions,这与上面类似,但也阻止任何人声明此BaseClass的实例,因为这会产生BaseClassAbstract,这意味着它是一个接口的想法。
      • 示例VirtualFunctionvirtual update();
      • 示例Purely Virtual: '虚拟更新() = 0;
  • Containers- (我会使用std::container,但我不会涉及任何Algorithms)

    有许多
    • 种容器可以满足不同的需求; 这些容器有助于保持程序简单,易于管理和调试,用户友好并防止将来出现许多麻烦,而不是使用basic C Arrays
    • 有几种不同的类型,它们都有自己的目的和属性,我不会详细介绍它们的所有细节,因为您可以在网上找到有关它们的大量信息,但我将它们标记为并分组到它们的相似属性:分组是Sequence ContainersAssociative ContainersUnordered Containers,这些都属于std::namespace。分组之间的主要区别是:Sequence Containersarrayslinked listsAssociative Containersbinary treesUnordered Containersbinary trees相似,只是它们不按顺序排列,它们被认为是hash tables
      • Sequence:vectordequeuequeuelistforward_listarray
      • Associative:setmultisetmapmultimap
      • Unordered:unordered_setunordered_multisetunordered_map, unordered_multimap'
    • 这些容器之所以强大,是因为能够快速遍历它们,或者根据您使用的容器快速插入和查找。另一个很好的功能是帮助内存管理过程。最后是可以对它们进行工作的众多algorithmsiterators
    • 有关stl的更多信息,我建议通过以下方式观看此YouTube系列Bo Qian
  • Smart Pointers有几种不同的类型,但最重要的两种是std::shared_ptr<T>std::unique_ptr<T>.两者之间的主要区别在于,shared对有多少对象可以访问它有一个reference count;这意味着它有一个公共类型接口,可以使用复制语义; 另一方面,unique一次只有1owner,它可以转让所有权,但一旦转让,原始所有者就无法再访问它。您不能复制unique,但可以移动它们。这些智能指针有助于使用dynamic memory和生命周期对象管理,以防止内存泄漏、无效指针、悬空指针和引用、未定义的行为等。它们分别有助于最大限度地减少newdeletenew[]&delete[]的使用。


现在您已经了解了C++程序中经常看到的一些概念;现在,我将向您展示我根据我认为您正在尝试做的事情编写的简单应用程序:

#include <array>
#include <exception>
#include <memory>
#include <string>
#include <iostream>  
class Person {
protected:      
std::string name_;
int tasksCompleted_;
public:
const std::string& whoIs() const { return name_; }
int numberTasksCompleted() const { return tasksCompleted_; }
virtual void performTask() = 0;
protected:
explicit Person(const std::string& name) : name_{ std::move(name) } {}
virtual ~Person() = default;
};
class Bodine final : public Person {
private:
static int currentTask;
public:
explicit Bodine(const std::string& name = std::string("Bodine")) : Person(name) {}
virtual ~Bodine() = default;
virtual void performTask() { currentTask++; tasksCompleted_ = currentTask;  }
};
int Bodine::currentTask = 0;
class Finn final : public Person {
private:
static int currentTask;
public:
explicit Finn(const std::string& name = std::string("Finn")) : Person(name) {}
virtual ~Finn() = default;
virtual void performTask() { currentTask++; tasksCompleted_ = currentTask; }
};
int Finn::currentTask = 0;
class Tycho final : public Person {
private:
static int currentTask;
public:
explicit Tycho(const std::string& name = std::string("Tycho")) : Person(name) {}
virtual ~Tycho() = default;
virtual void performTask() { currentTask++; tasksCompleted_ = currentTask; }
};
int Tycho::currentTask = 0;
int main() {
try {
std::array<std::shared_ptr<Person>, 3> people{
std::shared_ptr<Person>(new Bodine()),
std::shared_ptr<Person>(new Finn()),
std::shared_ptr<Person>(new Tycho())
};
// For each person in array
const int MAX_TASKS = 7;
int currentPerson = 0;
for (auto& p : people) {
std::cout << p->whoIs() << " has performed task #:n";
while (p->numberTasksCompleted() < 7) {
p->performTask();
std::cout << p->numberTasksCompleted() << 'n';
if (p->numberTasksCompleted() == MAX_TASKS) {
currentPerson++;
if (currentPerson <= (people.size() - 1) ) {
std::cout << "It's your turn " << people[currentPerson]->whoIs() << " to do some tasks.n";
}
break;
}
}
}
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;    
}

-输出-

Bodine has performed task #:
1
2
3
4
5
6
7
Finn has performed task #:
1
2
3
4
5
6
7
Tycho has performed task #:
1
2
3
4
5
6
7

链接到上面的程序。


我知道这需要阅读很多内容;但是请仔细查看应用程序,尝试看看它在做什么。您可以将其直接复制并粘贴到您自己的 IDE 中,并尝试构建并运行它以查看它的实际效果。希望这会让您了解C++是什么。


-编辑-

关于上面的代码:它比它真正需要的要复杂一些。首先,你不会真正看到一个人的身份,因为它是自己的阶级。我这样做只是为了证明inheritance是什么。我选择使用std::array而不是std::vector主要是因为您的提案中3了特定的人。如果在编译时人数未知,那么std::vector将是要使用的正确容器。您也不需要使用继承。此外,如果您查看派生classes3会有很多duplicate代码。我还使用shared_ptrs来展示如何使用它们,但在您的特定情况下不是必需的。我还在DerivedClasses中使用了static member variables来展示static storage

这是上述代码的简化版本,用于模仿您的行为。两个程序执行相同的任务类似,唯一的主要区别是:使用inheritancepurely virtual methodsstatic member storagecontainer type,以及通过使用shared_ptrdynamic memory

#include <exception>
#include <iostream>
#include <string>
#include <vector>    
class Person {
private:    
std::string name_;
int tasksCompleted_;
public:
explicit Person(const std::string& name) : name_(name), tasksCompleted_(0) {}
const std::string& whoIs() const { return name_; }
int numberTasksCompleted() const { return tasksCompleted_; }
void performTask() { tasksCompleted_++; }
};
int main() {
try {
std::vector<Person> people{
Person( "Bodine" ),
Person( "Finn" ),
Person( "Tycho" )
};
// For each person in array
const int MAX_TASKS = 7; // Don't like magic numbers!        
int currentPerson = 0; // Needed variable
for (auto& p : people) {
std::cout << p.whoIs() << " has performed task #:n";
while (p.numberTasksCompleted() < MAX_TASKS) {
p.performTask();
std::cout << p.numberTasksCompleted() << 'n';
if (p.numberTasksCompleted() == MAX_TASKS) {
currentPerson++;
if (currentPerson <= (people.size() - 1) ) {
std::cout << "It's your turn " << people[currentPerson].whoIs() << " to do some tasks.n";
}
break;
}
}
}
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;    
}

这是此版本程序的链接!