在排序对象向量的时候,为什么类的已创建对象计数会额外增加2?

huangapple go评论103阅读模式
英文:

Why at the moment of sorting the object vector the counter of created objects of the class is increased by an additional 2?

问题

这里有一个名为 HasPtr 的类:

  1. class HasPtr
  2. {
  3. friend void swap(HasPtr&, HasPtr&);
  4. public:
  5. HasPtr(const std::string& s = std::string())
  6. : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
  7. HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
  8. HasPtr& operator=(HasPtr hp)
  9. {
  10. swap(*this, hp);
  11. return *this;
  12. }
  13. ~HasPtr()
  14. {
  15. if (--*use == 0)
  16. {
  17. delete ps;
  18. delete use;
  19. }
  20. }
  21. bool operator<(const HasPtr& rhs)
  22. {
  23. return *ps < *rhs.ps;
  24. }
  25. private:
  26. unsigned i;
  27. std::size_t* use; // counter
  28. std::string* ps;
  29. };
  30. inline void swap(HasPtr& lhs, HasPtr& rhs)
  31. {
  32. using std::swap;
  33. swap(lhs.ps, rhs.ps);
  34. swap(lhs.i, rhs.i);
  35. }

主函数也初始化了一个向量,然后对其进行排序并显示结果:

  1. int main()
  2. {
  3. HasPtr a("A"), b("B"), c("C"), d("D"), e("E");
  4. std::vector<HasPtr> vec{d, a, c, e, b};
  5. std::sort(vec.begin(), vec.end());
  6. for (auto letter : vec)
  7. {
  8. std::cout << *letter.ps << " " << letter.get_use() << " " << std::endl;;
  9. }
  10. return 0;
  11. }

问题: 为什么向量中的每个对象都有一个计数器为3,如何修复这个问题?

要解决计数器为3的问题,您需要注意 HasPtr 类的拷贝构造函数和赋值操作符的实现。在当前实现中,拷贝构造函数没有正确地增加计数器,因此计数器会累积。为了修复这个问题,您可以改进拷贝构造函数和赋值操作符的实现,确保计数器正确地增加和减少。这可以通过在这两个函数中增加对 use 指针的引用计数的操作来实现。

以下是修复后的 HasPtr 类:

  1. class HasPtr
  2. {
  3. friend void swap(HasPtr&, HasPtr&);
  4. public:
  5. HasPtr(const std::string& s = std::string())
  6. : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
  7. HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
  8. HasPtr& operator=(HasPtr hp)
  9. {
  10. swap(*this, hp);
  11. return *this;
  12. }
  13. ~HasPtr()
  14. {
  15. if (--*use == 0)
  16. {
  17. delete ps;
  18. delete use;
  19. }
  20. }
  21. bool operator<(const HasPtr& rhs)
  22. {
  23. return *ps < *rhs.ps;
  24. }
  25. private:
  26. unsigned i;
  27. std::size_t* use; // counter
  28. std::string* ps;
  29. };

这样,每个对象的计数器就会正确地增加和减少,不再出现计数器为3的问题。

英文:

There is a HasPtr class:

  1. class HasPtr
  2. {
  3. friend void swap(HasPtr&amp;, HasPtr&amp;);
  4. public:
  5. HasPtr(const std::string&amp; s = std::string())
  6. : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
  7. HasPtr(const HasPtr&amp; hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
  8. HasPtr&amp; operator=(HasPtr hp)
  9. {
  10. swap(*this, hp);
  11. return *this;
  12. }
  13. ~HasPtr()
  14. {
  15. if (--*use == 0)
  16. {
  17. delete ps;
  18. delete use;
  19. }
  20. }
  21. bool operator&lt;(const HasPtr&amp; rhs)
  22. {
  23. return *ps &lt; *rhs.ps;
  24. }
  25. private:
  26. unsigned i;
  27. std::size_t* use; // counter
  28. std::string* ps;
  29. };
  30. inline void swap(HasPtr&amp; lhs, HasPtr&amp; rhs)
  31. {
  32. using std::swap;
  33. swap(lhs.ps, rhs.ps);
  34. swap(lhs.i, rhs.i);
  35. }

The main function also initializes the vector and then sorts and displays the result:

  1. int main()
  2. {
  3. HasPtr a(&quot;A&quot;), b(&quot;B&quot;), c(&quot;C&quot;), d(&quot;D&quot;), e(&quot;E&quot;);
  4. std::vector&lt;HasPtr&gt; vec{d, a, c, e, b};
  5. std::sort(vec.begin(), vec.end());
  6. for (auto letter : vec)
  7. {
  8. std::cout &lt;&lt; *letter.ps &lt;&lt; &quot; &quot; &lt;&lt; letter.get_use() &lt;&lt; &quot; &quot; &lt;&lt; std::endl;;
  9. }
  10. return 0;
  11. }

Question: Why does it turn out that every object in the vector has a counter of 3 and how can this be fixed?

答案1

得分: 3

插入到向量中会创建第二个副本,将使用计数增加到 2

然后,您有循环 for (auto letter : vec),它使用 进行迭代。也就是说,它在向量内部创建对象的副本,使计数在循环内部增加到 3

如果您改为使用引用进行迭代,就像 for (auto const&amp; letter : vec),那么使用计数应该保持在 2

英文:

Inserting into a vector will create a second copy, increasing the use-count to 2.

Then you have the loop for (auto letter : vec) which iterates using values. I.e. it creates copies of the object inside the vector, increasing the count to 3 while inside the loop.

If you iterate using references instead, as in for (auto const&amp; letter : vec), then the use-count should be left at 2.

huangapple
  • 本文由 发表于 2023年2月27日 17:09:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75578535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定