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

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

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

问题

这里有一个名为 HasPtr 的类:

class HasPtr
{
    friend void swap(HasPtr&, HasPtr&);
public:
    HasPtr(const std::string& s = std::string()) 
       : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
    HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
    HasPtr& operator=(HasPtr hp)
    {
        swap(*this, hp);
        return *this;
    }
    ~HasPtr()
    {
        if (--*use == 0)
        {
            delete ps;
            delete use;
        }
    }
    bool operator<(const HasPtr& rhs)
    {
        return *ps < *rhs.ps;
    }
private:
    unsigned i;
    std::size_t* use; // counter
    std::string* ps;
};

inline void swap(HasPtr& lhs, HasPtr& rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);
    swap(lhs.i, rhs.i);
}

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

int main()
{
    HasPtr a("A"), b("B"), c("C"), d("D"), e("E");
    std::vector<HasPtr> vec{d, a, c, e, b};
    std::sort(vec.begin(), vec.end());
    for (auto letter : vec)
    {
        std::cout << *letter.ps << " " << letter.get_use() << " " << std::endl;;
    }

    return 0;
}

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

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

以下是修复后的 HasPtr 类:

class HasPtr
{
    friend void swap(HasPtr&, HasPtr&);
public:
    HasPtr(const std::string& s = std::string()) 
       : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
    HasPtr(const HasPtr& hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
    HasPtr& operator=(HasPtr hp)
    {
        swap(*this, hp);
        return *this;
    }
    ~HasPtr()
    {
        if (--*use == 0)
        {
            delete ps;
            delete use;
        }
    }
    bool operator<(const HasPtr& rhs)
    {
        return *ps < *rhs.ps;
    }
private:
    unsigned i;
    std::size_t* use; // counter
    std::string* ps;
};

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

英文:

There is a HasPtr class:

class HasPtr
{
    friend void swap(HasPtr&amp;, HasPtr&amp;);
public:
    HasPtr(const std::string&amp; s = std::string()) 
       : ps(new std::string(s)), i(0), use(new std::size_t(1)) {}
    HasPtr(const HasPtr&amp; hp) : ps(hp.ps), i(hp.i), use(hp.use) { ++*use; }
    HasPtr&amp; operator=(HasPtr hp)
    {
        swap(*this, hp);
        return *this;
    }
    ~HasPtr()
    {
        if (--*use == 0)
        {
            delete ps;
            delete use;
        }
    }
    bool operator&lt;(const HasPtr&amp; rhs)
    {
        return *ps &lt; *rhs.ps;
    }
private:
    unsigned i;
    std::size_t* use; // counter
    std::string* ps;
};

inline void swap(HasPtr&amp; lhs, HasPtr&amp; rhs)
{
    using std::swap;
    swap(lhs.ps, rhs.ps);
    swap(lhs.i, rhs.i);
}

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

int main()
{
    HasPtr a(&quot;A&quot;), b(&quot;B&quot;), c(&quot;C&quot;), d(&quot;D&quot;), e(&quot;E&quot;);
    std::vector&lt;HasPtr&gt; vec{d, a, c, e, b};
    std::sort(vec.begin(), vec.end());
    for (auto letter : vec)
    {
        std::cout &lt;&lt; *letter.ps &lt;&lt; &quot; &quot; &lt;&lt; letter.get_use() &lt;&lt; &quot; &quot; &lt;&lt; std::endl;;
    }

    return 0;
}

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:

确定