【问题标题】:How to change to avoid copying the contents of the pointers如何更改以避免复制指针的内容
【发布时间】:2015-07-30 12:54:51
【问题描述】:

编辑 3

我有以下代码

std::shared_ptr<int> original = std::make_shared<int>(5);
std::shared_ptr<int> other = std::make_shared<int>(6);
std::stack<std::shared_ptr<int>> todo;
todo.push(original);
std::shared_ptr<int> temp = todo.top();
*temp = *other;

std::cout << original << other << temp << std::endl;

original 现在指向资源6,然后控制台中的输出为666。 我喜欢避免复制*temp = *other,因为我在指针和堆栈中使用的实际值复制起来很昂贵。

【问题讨论】:

  • 您更愿意将 p1 的旧值与 P2s 值结转吗?这就是你要找的吗?
  • 也许我不明白...But what is wrong with p1 = p2;?
  • p2.swap(p1); 不会成功吗?
  • @satanik 每个人都很难理解你在问什么。假设您有两个 shared_ptrs,都拥有相同的资源 - auto p1 = std::make_shared&lt;int&gt;(10); auto p2 = p1; 现在您想要发生什么?是否要将10 替换为另一个值,以便*p1*p2 都产生新值?还是你在问别的?除非有必要,否则我建议删除 shared_ptr&lt;shared_ptr&lt;int&gt;&gt; 示例,并以简单的方式解释您的问题。
  • 你更容易理解的例子不是

标签: c++ pointers c++11 shared-ptr smart-pointers


【解决方案1】:

你只需要继续使用指向指针的指针。

//we need to make shared pointer to shared pointer
const std::shared_ptr<std::shared_ptr<int>> orginal = 
        std::make_shared<std::shared_ptr<int>>(std::make_shared<int>(5));
// const pp1 must be declarated before p1 to make sure p1 is valid 
std::shared_ptr<int> &p1 = *orginal;
std::shared_ptr<int> p2 = std::make_shared<int>(6);
cout << *p1 << *p2 << endl;
std::stack<std::shared_ptr<std::shared_ptr<int>>> todo;
//we cannot add p1, instead we need to add orginal
todo.push(orginal); 
std::shared_ptr<std::shared_ptr<int>> temp = todo.top();
//this does change the orginal
*temp = p2;
cout << *p1 << *p2 << endl;

不,您不能以这种方式更改p2,它位于堆栈上,并且将指向堆栈的指针保留在 shared_ptr 中将非常难以理解。

无论如何,我认为您可能会寻找享元模式,see this

【讨论】:

  • 有没有办法在不使original 成为指针的情况下做到这一点?因为在我的情况下它只是一个指针并且经常被使用。因此,如果我以这种方式更改它,我也必须更改所有其他代码。
  • @satanik 不,你不能安全地做到这一点。正如我所说的 p2 不能在我的例子中。但是,只要您保留指向指针的原始指针的一项版权,就可以使用引用 p1。如果您在同样由 stared_ptr 管理的结构中声明 p2,则可以将 stared_ptr 转换为我们的指针。
【解决方案2】:

我认为如果您使用 weak_ptr 作为堆栈的模板参数,您可以实现您想要的:

std::shared_ptr<int> original = std::make_shared<int>(5);
std::shared_ptr<int> other = std::make_shared<int>(6);
std::stack<std::weak_ptr<int>> todo;
todo.push(original);
std::weak_ptr<int> temp = todo.top();
temp=other;

std::cout << *original.get() << *other.get() << *temp.lock().get() << std::endl;
std::cout<<"use_count: original:"<< original.use_count()<<"\n";
std::cout<<"use_count: other:"<< other.use_count()<<"\n";

输出: 566

use_count: original:1

使用次数:其他:1

编辑:

std::shared_ptr<int> original = std::make_shared<int>(5);
std::shared_ptr<int> other = std::make_shared<int>(6);
std::stack<std::weak_ptr<int>> todo;
todo.push(original);
std::weak_ptr<int> temp = todo.top();
temp=other;
original= other;

std::cout << *original.get() << *other.get() << *temp.lock().get() << std::endl;
std::cout<<"use_count: original:"<< original.use_count()<<"\n";
std::cout<<"use_count: other:"<< other.use_count()<<"\n";
std::cout<<"use_count: temp:"<< temp.use_count()<<"\n";

输出: 666

use_count: original:2

使用次数:其他:2

use_count: temp:2

【讨论】:

  • 但这正是我不能使用的,因为我稍后使用的实际p1p1 的副本。我把它写在之前的描述和作业正上方的评论中。我将指针传递给例如一个堆栈然后再次检索它,堆栈复制它然后它是另一个指针,如果我然后分配stack.top() = p2 - p1 仍将保留原始值
  • 你应该说,*p2 的进一步变化将反映在*p1 中。因为您实际声称“p2 的任何进一步变化也会反映在 p1 中”是不正确的。
  • 我想要输出666 所以*origianl 应该是6
  • @Steephen:我看到这行得通,但我需要在分配temp = other 时创建*original == 6,因为此时程序original 不可用(例如,在循环中 temp是堆栈的当前值,但不一定是original 指针)
猜你喜欢
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2015-03-28
  • 2018-07-22
  • 1970-01-01
  • 2016-10-13
  • 2021-11-19
  • 2021-10-13
相关资源
最近更新 更多