为每个对象增加一个计数器
incrementing a counter for every object
我有一个 class 叫做 Student
,在那 class 我有一个 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()
returns 每个 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_student
和 new_student_1
。
有人可以帮我吗?
您的代码的问题是每个 Student
对象都有自己的 std::map
副本。您需要他们共享一个 std::map
对象。
共享books
字段的最简单方法是使它成为Student
的static
成员,那么你根本不需要复制它,例如:
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()
本身的局部变量,然后你可以将 pointer/reference 传递给每个 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::vector
个 std::shared_ptr<Book>
对象,以共享单个图书对象而不仅仅是字符串,而不是管理您自己的完全没有计数器(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("...");
...
}
我有一个 class 叫做 Student
,在那 class 我有一个 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()
returns 每个 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_student
和 new_student_1
。
有人可以帮我吗?
您的代码的问题是每个 Student
对象都有自己的 std::map
副本。您需要他们共享一个 std::map
对象。
共享books
字段的最简单方法是使它成为Student
的static
成员,那么你根本不需要复制它,例如:
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()
本身的局部变量,然后你可以将 pointer/reference 传递给每个 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::vector
个 std::shared_ptr<Book>
对象,以共享单个图书对象而不仅仅是字符串,而不是管理您自己的完全没有计数器(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("...");
...
}