英文:
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&, 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);
}
The main function also initializes the vector and then sorts and displays the result:
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;
}
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& 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& letter : vec)
, then the use-count should be left at 2
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论