为每个对象递增一个计数器



我有一个名为Student的类,在这个类中,我有一个std::map的书籍,它看起来像这样:

std::map<std::string,int>books;

string为书名,int为拥有同一本书的学生人数。

然后我创建了一个新的Student,当我这样做的时候,我想让Student也得到同样的书,所以我做了一个这样的复制:

new_student->getBookmap() = old_student->getBookmap();
new_student_3->getBookmap() = old_student->getBookmap();

getBookmap()返回每个Student对应的map。我把他们作为private成员。

新的Student获得相同的map的精确副本,现在我想增加计数器,但计数器也应该为所有三个Student增加。

但是,如果我增加一个Student的计数器,其他Student的计数器不会增加。

for (auto it = new_student->getBookmap().begin(); it != new_student->getBookmap().end(); it++)
{
it->second++;
}

当我这样做时,计数器只增加new_student,而不增加old_studentnew_student_1

有人能帮我一下吗?

代码的问题是每个Student对象都有自己的std::map副本。您需要它们共享一个std::map对象。

共享books字段最简单的方法是使其成为Studentstatic成员,然后你根本不需要复制它,例如:

using bookCounter = std::map<std::string, int>;
class Student {
private:
static bookCounter books;
...
void checkoutBook(std::string bookName);
void returnBook(std::string bookName);
...
};
bookCounter Student::books;
void Student::checkoutBook(std::string bookName)
{
books[bookName]++;
}
void Student::returnBook(std::string bookName)
{
books[bookName]--;
}
int main()
{
...
new_student = new Student();
new_student->checkoutBook("...");
...
new_student->returnBook("...");
...
}

或者,您可以将books声明为全局变量,例如在main()附近,然后在需要时仅在Students内部引用该变量,例如:

class Student {
...
};
using bookCounter = std::map<std::string, int>;
extern bookCounter books;
void Student::checkoutBook(std::string bookName)
{
books[bookName]++;
}
void Student::returnBook(std::string bookName)
{
books[bookName]--;
}
bookCounter books;
int main()
{
...
}

或者,您可以使books成为main()本身的局部变量,然后您可以将指针/引用传递给每个Student,例如:

using bookCounter = std::map<std::string, int>;
class Student {
private:
bookCounter &books;
...
public:
Student(bookCounter &books) : books(books) {}
...
void checkoutBook(std::string bookName);
void returnBook(std::string bookName);
...
};
void Student::checkoutBook(std::string bookName)
{
books[bookName]++;
}
void Student::returnBook(std::string bookName)
{
books[bookName]--;
}
int main()
{
bookCounter books;
...
new_student = new Student(books);
new_student->checkoutBook("...");
...
new_student->returnBook("...");
...
}
或者,您可以考虑使用std::shared_ptr在各种Student对象之间共享单个std::map对象,例如:
using bookCounter = std::map<std::string, int>;
class Student {
private:
std::shared_ptr<bookCounter> books;
...
public:
Student(std::shared_ptr<bookCounter> books) : books(books) {}
...
void checkoutBook(std::string bookName);
void returnBook(std::string bookName);
...
};
void Student::checkoutBook(std::string bookName)
{
(*books)[bookName]++;
}
void Student::returnBook(std::string bookName)
{
(*books)[bookName]--;
}
int main()
{
auto books = std::make_shared<bookCounter>();
...
new_student = new Student(books);
new_student->checkoutBook("...");
...
new_student->returnBook("...");
...
}

在这种情况下,您可以考虑将std::map更改为std::shared_ptr<Book>对象的std::vector,以共享单个图书对象而不仅仅是字符串,并且根本不管理您自己的计数器(std::shared_ptr有自己的计数器,您可以通过其use_count()方法查询),例如:

struct Book : std::enable_shared_from_this<Book>
{
std::string name;
...
int checkoutCount() const;
[[nodiscard]] static std::shared_ptr<Book> create();
private:
Book() = default;
};
using bookPtr = std::shared_ptr<Book>;
class Student {
private:
std::vector<bookPtr> books;
...
public:
...
void checkoutBook(std::string bookName);
void returnBook(std::string bookName);
...
};
std::vector<bookPtr> library;
std::shared_ptr<Book> Book::create()
{
return std::shared_ptr<Book>(new Book);
}
int Book::checkoutCount() const
{
auto pthis = shared_from_this();
return (pthis.use_count() - 2); // not counting pthis and the library ...
}
void Student::checkoutBook(std::string bookName)
{
auto iter = std::find_if(library.begin(), library.end(),
[&](bookPtr &book){ return book->name == bookName; }
);
if (iter != library.end())
books.push_back(*iter);
}
void Student::returnBook(std::string bookName)
{
auto iter = std::find_if(books.begin(), books.end(),
[&](bookPtr &book){ return book->name == bookName; }
);
if (iter != books.end())
books.erase(*iter);
}
int main()
{
// populate library with Books as needed...
...
new_student = new Student();
new_student->checkoutBook("...");
...
new_student->returnBook("...");
...
}

相关内容

  • 没有找到相关文章

最新更新