【问题标题】:How can I do this with Smart Pointers?如何使用智能指针做到这一点?
【发布时间】:2012-05-16 05:13:36
【问题描述】:

这是我想要实现的目标:

#include <iostream>
using std::cout;

#include <vector>
using std::vector;

int main()
{
    vector<int> a {3, 7};

    int *p = &a.at (0); //assign 3

    for (int i = 0; i < 10; ++i) //swap and print (3,7,3...)
    {
        p = (*p == a.at (0) ? &a.at (1) : &a.at (0));
        cout << *p << '\n';
    }
}

我想使用智能指针而不是原始指针,看看它们如何更好,但无法真正弄清楚如何实现来回切换(这用于在游戏中轮流使用; 这是Player *)。

我尝试在两个单独的测试中用std::unique_ptrstd::shared_ptr 替换这里的指针,使用reset 进行切换,在第一个之后都给出随机数,正如预期的那样。

接下来,我尝试了std::weak_ptr,因为它看起来像我需要的,尽管界面并不是那么相似。据我所见,使用它的唯一方法是通过lock(),所以我尝试将lock(). 附加到reset 的调用中,并将其附加到取消引用中,但它崩溃了。

如何使用std::weak_ptr 代替原始指针,或者我可以以某种方式实际使用其他指针之一?

【问题讨论】:

  • 这里不需要weak_ptr,因为没有循环。为什么 shared_ptr 不工作?我建议发布那个代码,你得到的错误,并在那里寻求帮助。 unique_ptr 将不起作用,因为...只有一个人可以指向同一个东西...它是唯一的
  • @CrazyEddie,共享指针不起作用,因为它是唯一指向它的指针,所以当它切换到另一个玩家时,没有任何东西指向第一个。

标签: c++ c++11 segmentation-fault smart-pointers weak-ptr


【解决方案1】:

我认为您应该考虑使用std::vector::iterator,而不是使用原始指针进行这种类型的索引操作,请记住,任何插入std::vector 的操作都可能使迭代器无效。例如,您可以执行以下操作:

typedef std::vector<int>::iterator iter_t;

vector<int> a {3, 7};

iter_t p = iter_t(&a.at(0)); //assign 3

for (int i = 0; i < 10; ++i) //swap and print (3,7,3...)
{
    p = (*p == a.at(0) ? iter_t(&a.at(1)) : iter_t(&a.at(0)));
    cout << *p << '\n';
}

【讨论】:

  • 删除是个意外 :p 我将如何使用迭代器呢?
  • 虽然其他人也有优点,但我最喜欢这个。谢谢。
【解决方案2】:

根据定义,智能指针并不是“好得多”。它们仅在需要管理所指向的内存时才有用。

由于您的指针只是指向vector 中的元素,因此您根本不需要智能指针。大多数智能指针会在超出范围时尝试删除它们指向的内存,在这种情况下会导致鼻恶魔。

但请注意,调整向量的大小可能会导致所有指针无效。确保在指针仍在作用域内时不要添加或删除元素。

在这种情况下,玩家轮流,我可能根本不会使用指针,而是这样的:

int main()
{
    vector<int> players {3, 7};

    int current_player = 0;

    while (!game_over())
    {
        cout << players[current_player] << '\n';
        current_player = (current_player + 1) % players.size();
    }
}

【讨论】:

  • 我明白了,我误解了它们的用法。我确实记得读过一些东西,只是使用一个普通的指针来指向后面的东西。不过从技术上讲,我现在有课,所以我会离开一会儿。
  • @chris:然后见this question
  • @Xeo,非常有用,谢谢。我在搜索时从未真正找到那个。
【解决方案3】:

刚刚意识到您可能意味着您想要一个指向向量中 int 的智能指针,而不是将向量中的整数更改为智能指针。我根本不会那样做。我会使用向量的迭代器:

for (int i = 0; i < 10; ++i) {
  auto it = it.begin() + (i % 2 ? 1:0);
  f(*it);
}

使用 shared、unique 或任何其他指向向量内部的指针会导致糟糕的、糟糕的、糟糕的事情。也不保证使用原始指针,因为它们不指示任何关于它们所指向的内容。另一方面,向量的迭代器虽然可能以原始指针的形式实现,但对于它们的使用有明确的、记录在案的规则,您可以通过使用它们在代码中记录这些规则。

不要忘记“智能指针”包括迭代器。

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    相关资源
    最近更新 更多