所以我已经建立了这个任务系统,或者我正在尝试建立它,以便如果某人完成了七个以上的任务,那么下一个人必须完成七个。
双打(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,所以是。。。)。我只需要知道如何使用下一个变量!
答案 0 :(得分:2)
好吧,您并没有真正掌握该轮到谁。另外,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
并宣布在调用{{1 }}设置该权限。
然后您可以根据需要拨打advanceUser
,例如,我对它进行了如下测试:
incrementTasksDone
例如,这将完成100个任务,因此转弯过程中将更改14次,并且每次都会打印消息。
此外,要使该示例运行,请确保添加以下内容:
int main()
{
for (int i = 0; i < 100; i++) {
incrementTasksDone();
}
}
答案 1 :(得分:0)
您好,欢迎使用C ++。许多人会说C ++对于初学者来说是一种不好的选择。好吧,我很早以前就开始使用C ++,但直到今天我仍然在学习。我是100%自学的,我不具备当今人们在互联网上可获得的大量信息以及现代格式所具有的优势。当我刚开始学习C ++时,互联网正处于蓬勃发展的阶段。但是当时的大多数网站几乎都是纯文本,即使是简单的图片或图形也要花一些时间才能加载到屏幕上,因为这是在Dial Up
时代。今天,刚起步的人同时拥有该网站,其他类似网站甚至youtube视频的优势。但是,我仍然乐于提供帮助,因为它不仅可以帮助您,而且还可以帮助我改善已经学到的知识。 C ++已经发展了很多年,因此我在这里向您展示的是一个小型应用程序,我相信它可以模仿您所描述的行为。这些技巧中的一些技巧特别是对于初学者而言有些先进,但是我认为新手早点学习这些概念是很合适的。
Storage Types & Lifetime
-C++
中基本上有4种主要存储类型:Automatic
,Dynamic
,Static
和Thread
。我主要关注前3个。
- ,它将自动销毁。
Automatic:
具有声明它的作用域的生命周期,并且一旦该作用域退出其右括号}
Dynamic:
由指针表示但用new
声明且必须具有匹配的delete
或分别为数组new[]
和delete[]
的内存。它们的生存期可以长于它们声明的作用域。它们将生存到调用其匹配的delete为止。如果没有匹配的删除发生,则会导致内存泄漏,无效的指针,悬空的指针和引用以及未定义的行为。使用raw-pointers
时需要特别注意;建议使用containers
或smart pointers
。Static:
通常在global
命名空间和global filespace
中找到。如果在static
中声明了main.cpp
,它将具有应用程序的生命周期和整个程序的范围。如果在其他cpp
文件中声明了它们,则将具有该文件的范围,除非在某个header
文件中声明了它们,则它们将具有其他翻译单元包括该标头的范围。它们在Automatic
的意义上类似于它们将被自动销毁,但是它们的区别在于它们仅被初始化一次,保持其状态并且您只能拥有它们的一个实例。- 有关不同类型的存储分类的演示,请参见我以前对此Q/A的回答。
Classes and Inheritance:
-(我不会涉及Polymorphism
)。
Classes:
Classes
和Structs
是用户定义的数据类型。- 两者之间的区别是默认访问权限
- 默认情况下:
Structs
有Public Members
和Classes
有Private Members
Class
或Struct
的成员可以是任何内置类型,类型的指针,另一种用户定义的数据类型以及方法或函数。Member Variables
可以是任意Storage
Type
的成员:Automatic
,Dynamic
,Static
和Thread
,但是,成员函数通常是Automatic
,但可以是Static
。如果您有member variable
,则必须在initialized
Class's
之外的Declaration
处解决symbols
。- 默认情况下,它们具有
Constructors
和Destructors
,但是人们可以创建自己的自定义Constructor
或Destructor
。您通常会看到人们用他们的简称来分别提及他们:ctor
和dtor
。- 一个类可以从另一个类继承。
Inheritance:
- 您有
Base
或Super
Classes
,并且您有Derived
或Child
Classes
- 当来自
Inheriting
类的Base
时,如果Base
类的ctor
为Public
,则意味着您可以创建两个{{ 1}}和Base
Derived
。有时您想要这种设计,但是有时候您不想要。- 如果您不希望用户能够创建
Classes
Base
的实例,而是能够创建Class
的实例,那么您需要做的所有事情确保 1 st 的Derived Class
为ctor
。如果您声明Protected
,那么即使您的Private
Derived
也无法访问它,因此也无法声明它们。 * 2nd您要确保您的Classes
-Destructors
为dtors
;否则,您将对销毁类的顺序有疑问。- 一个
Virtual
Base
可以有Class
个Member Functions
,这意味着所有Virtual
Derived
必须Classes
{{1} 1}}。Implement
Function
可以具有Base
的{{1}},与上面类似,但也阻止任何人声明此Class
{ 1}},因为这使Member Functions
Purely Virtual
Base
成为界面的一个想法。- 示例
Class
Base
:Class
- 示例
Abstract
:`虚拟update()= 0;
Virtual
-(我将使用Function
,但不会涉及任何virtual update();
)
- 有多种容器可以满足不同的需求;这些容器有助于使您的程序简单,易于管理和调试,易于使用,并避免将来出现许多麻烦,而不是使用
Purely Virtual
。- 有几种不同的类型,它们各自具有自己的目的和属性,我将不赘述它们的所有详细信息,因为您可以在网上找到有关它们的大量信息,但我将其标记并分组为它们具有相似的属性:分组为
Containers
,std::container
和&Algorithms
,它们都属于basic C Arrays
Sequence Containers
。分组之间的主要区别在于:Associative Containers
像Unordered Containers
和std::
,namespace
像Sequence Containers
,而arrays
与{ {1}}(除非顺序不正确)被视为linked lists
。
Associative Containers
binary trees
,Unordered Containers
,binary trees
,hash tables
,Sequence:
,vector
dequeue
queue
,list
,forward_list
,array
Associative:
set
,multiset
,map
,unordered_multimap`- 使这些容器功能强大的原因是能够快速遍历它们或根据所使用的容器快速插入和查找的能力。另一个好的功能是在内存管理过程中提供帮助。最后是众多
multimap
和Unordered:
可以在它们上完成的工作。- 有关
unordered_set
的更多信息,我建议观看unordered_multiset
的{{3}} YouTube系列
unordered_map
有几种不同的类型,但是最重要的两种是algorithms
和iterators
。两者之间的主要区别在于stl
对于有多少对象可以访问它具有Bo Qian
;这意味着它具有公共类型的接口,并且可以使用复制语义;另一方面,Smart Pointers
一次只能拥有std::shared_ptr<T>
std::unique_ptr<T>
,它可以转让所有权,但一旦这样做,原始所有者将无法再访问它。您无法复制shared
,但可以移动它们。这些智能指针有助于使用reference count
和生命周期对象管理,以防止内存泄漏,无效指针,悬空指针和引用,未定义行为等。它们有助于最小化unique
和{{ 1}}和1
和owner
。
现在,您已经了解了在unique
程序中经常看到的一些概念;现在,我将基于您认为您正在尝试做的事情向您展示我编写的简单应用程序:
dynamic memory
-输出-
new
this至以上程序。
我知道这要读很多;但是请仔细查看该应用程序,以查看其运行状况。您可以将此权限复制并粘贴到自己的IDE中,并尝试构建和运行它以查看其运行情况。希望这可以使您了解delete
是什么。
-编辑-
关于上面的代码:它比实际需要的要复杂一些。首先,您不会真正看到一个人的身份,因为它是自己的阶级。我这样做只是为了证明new[]
是什么。我选择使用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
将是使用的正确容器。您也不需要使用继承。另外,如果您查看派生自C++
的{{1}},则有很多inheritance
代码。我还使用std::array
展示了如何使用它们,但在您的特定情况下不是必需的。我还使用了std::vector
3
中的std::vector
来显示3
。
这里是上述代码的简化版本,用于模仿您的行为。两种程序都相似地完成相同的任务,唯一的主要区别是:通过使用classes
与duplicate
,shared_ptrs
,static member variables
和Derived
一起使用的Classes
。
static storage
这里是此程序版本的Link!