【发布时间】:2021-08-28 07:21:14
【问题描述】:
我正在处理一个项目并与shared_ptr 打交道。该程序正在运行并提供正确的输出。然而,在查看日志时,我注意到在程序中的某些点,引用计数具有特定值。示例可重现程序如下所示:
示例程序
#include <iostream>
#include<vector>
#include<string>
#include<utility>
#include<memory>
class NAME
{
public:
std::string name;
int age = 12;
NAME(std::string m_name, int m_age):name(m_name), age(m_age)
{
std::cout<<"NAME Parametrised "<<std::endl;
}
NAME(const NAME& rhs):name(rhs.name), age(rhs.age)
{
std::cout<<"NAME Copy constructor"<<std::endl;
}
};
class SURNAME
{
public:
std::vector<std::vector<std::shared_ptr<NAME>>> vec_2d;
SURNAME(const std::vector<std::vector<std::shared_ptr<NAME>>> &m_vec):vec_2d(m_vec)
{
std::cout<<"Refernce count in SURNAME para constructor: "<<vec_2d.at(0).at(0).use_count()<<std::endl;
}
};
class AN
{
public:
std::vector<SURNAME> vec_SURNAME;
};
int main()
{
std::vector<std::shared_ptr<NAME>> temp_vector;
temp_vector.reserve(3);
temp_vector.push_back(std::make_shared<NAME>("MIDDLE",43));
temp_vector.push_back(std::make_shared<NAME>("LAST",54));
temp_vector.push_back(std::make_shared<NAME>("ANOTHERLAST",54));
std::vector<std::vector<std::shared_ptr<NAME>>> temp_2dvec;
temp_2dvec.reserve(1);
temp_2dvec.push_back(temp_vector);//reference count becomes 2
AN obj;
obj.vec_SURNAME.push_back(temp_2dvec);//reference count becomes 3
return 0;
}
上述程序的输出
NAME Parametrised
NAME Parametrised
NAME Parametrised
Reference count in SURNAME para constructor: 3
正如我们在输出中看到的,构造函数中的引用计数为 3。我认为当我们写temp_2dvec.push_back(temp_vector);时引用计数增加1,然后当我们写obj.vec_SURNAME.push_back(temp_2dvec);时引用计数再次增加1,最后变成3。现在我的问题是:
- 有没有办法避免这种引用计数的增加,而是移动 share_ptr 的?如果是,那怎么办?例如,我尝试使用
temp_2dvec.push_back(std::move(temp_vector));,然后在此步骤中引用计数没有增加。在这一步中这样做可以吗?还是某种 UB? - 当我尝试做同样的事情并使用语句
obj.vec_SURNAME.push_back(std::move(temp_2dvec));时,即使我在这里使用 std::move(),引用计数仍然会增加。这是怎么回事? - 请注意,变量
temp_vector和temp_2dvec只是我用来保存向量的临时变量。它们仅用于推送目的一次。所以我不会使用它们。所以离开他们是安全的。我怎样才能安全地实现这一点,即推入向量时不应该增加引用计数? - 另外,我的 2 个 cmets 是否正确(我写在主程序语句右侧的那些)?也就是说,引用计数在这两个步骤中增加了,或者它们在我缺少的程序的其他一些区域/步骤中增加了。
【问题讨论】:
标签: c++ c++11 c++14 shared-ptr smart-pointers