【问题标题】:Creating a standard queue of pointers in c++在 C++ 中创建一个标准的指针队列
【发布时间】:2012-12-06 07:58:40
【问题描述】:

假设我有一个整数队列,

#include <iostream>
#include <queue>
using namespace std;


int main() {

    int firstValToBePushed = 1;

    queue<int> CheckoutLine;

    CheckoutLine.push(firstValeToBePushed);

    cout << CheckoutLine.front();

    return 0;
}

我怎样才能使用一个包含指向整数的指针的队列来做本质上相同的事情,而不是像上面目前所做的那样。我计划制作一个循环来产生多个值,但这只是一个更简单的例子。

谢谢,

【问题讨论】:

  • 您需要指向整数的指针的最终要求是什么?就定义而言,queue&lt;int*&gt; CheckoutLine; 就是您想要的。
  • 正如@KarthikT 所说,这在很大程度上取决于您的任务。问题是,你打算用指针做什么?您想动态分配和删除存储在队列中的整数吗?请记住,int 的大小通常等于指针的大小,因此直接传递整数不会浪费任何空间。
  • 我最终想要获取这些将引用类的对象的指针,将它们存储在队列中,然后能够将它们从队列中移出到列表中。我在上面的例子中使用了整数,因为为了这个问题,它们更简单。
  • @Joe 对象的类型相对无关。你也不需要指针,从你目前的描述来看,你应该在这里使用指针。

标签: c++ pointers queue


【解决方案1】:

如果这是为了终身管理,那么:

std::queue<std::shared_ptr<int>> CheckoutLine;
CheckoutLine.push(std::make_shared<int>(firstValeToBePushed))

如果您的队列有点像代理,并且其他人实际上拥有对象的生命周期,那么肯定:

std::queue<std::reference_wrapper<int>> CheckoutLine;
CheckoutLine.push(firstValeToBePushed)

如果您没有在任何地方公开队列并且它是内部的,那么存储指针就可以了,正如其他人所建议的那样。

但是,永远不会向客户端公开指针集合,这是最糟糕的事情,因为您将管理生命周期的负担留给了它们,这对集合来说更麻烦。

当然对于原始类型或 POD,只需复制即可,无需存储指针。移动语义即使对于非 POD 也很容易,除非您有一些棘手的构造或者您的对象无法实现移动语义。

#include &lt;functional&gt;std::reference_wrapper#include &lt;memory&gt;std::shared_ptrstd::unique_ptr 和朋友。我假设您可以使用现代编译器。

【讨论】:

    【解决方案2】:

    为你添加一个循环。

    #include <iostream>
    #include <queue>
    using namespace std;
    
    int main() {
    
    queue<int*> theQueue;
    char c = 'n';
    
    while (c == 'n') {
      cout << "Enter \'n\' to add a new number to queue ( \'q\' to quit):";
      cin >> c;
      if ( c == 'q') {
        break;
      }
      else {
        int num;
        cout << "Enter an integer and press return: ";
        cin >> num;
        theQueue.push(new int(num));
      }
    }
    
    while( !theQueue.empty() ) {
      cout << theQueue.front() << ": " << *theQueue.front() << endl;
          delete theQueue.front();
      theQueue.pop();
    }
    return 0;
    }
    

    【讨论】:

      【解决方案3】:
      #include <iostream>
      #include <queue>
      using namespace std;
      
      
      int main()
      {
      int  value = 1337;
      
      int* firstValeToBePushed = &value;
      
      
      queue<int*> CheckoutLine;
      
      
      
      CheckoutLine.push(firstValeToBePushed);
      
      
      cout << *(CheckoutLine.front()) << "is at " << CheckoutLine.front();
      
      return 0;
      
      }
      

      【讨论】:

      • 我知道这只是为了说明目的,但在容器中存储指向基于堆栈的对象的指针总是值得怀疑的。
      • @Mat 可以说比存储指向基于堆的对象的原始指针更好。只要指针不授予所有权,两者都是等价的。
      • 是的,但它显示了如何使用它。舒尔你可以用int* firstValToBePushed = malloc(sizeof(int)); *firstValToBePushed = 1337; 替换int* firstValToBePushed = &amp;value;,但是为什么要把它复杂化以进行说明
      • @kenny malloc 在 C++ 中没有位置(如果没有强制转换,代码将无法编译)。
      • @Mat Dunno。两者都很容易用适当的工具捕捉。我担心此类指针的 valid 使用,非拥有指针(指向基于堆或基于堆栈的内存)完全没问题。 不好的是拥有内存的原始指针。如果我在现代 C++ 代码中看到这一点,我会立即认为这是一个错误。
      【解决方案4】:

      我不太明白,也许你想这样做:

      #include <iostream>
      #include <queue>
      
      using namespace std;
      
      int main(){
          int firstValueToBePushed = 1;
      
          queue<int *> CheckoutLine;
      
          CheckoutLine.push(new int(firstValueToBePushed));
      
          cout << *CheckoutLine.front() << endl;
      
          return 0;
      }
      

      【讨论】:

      • ……你正在泄漏内存。
      • 是否可以通过使用解构函数来修复此内存泄漏?
      • 在我的代码中,您必须创建一个接收“CheckoutLine.front()”的指针,并在 cout 之后对该指针执行删除操作。当您在指针上使用 delete 或对静态变量自动使用时,会调用析构函数。
      • @JoeElder 不,在这种情况下,析构函数是行不通的。您必须确保在离开范围之前删除队列中的所有元素(在本例中为 main 函数)。
      • 我使用带有析构函数而不是 int 类型的自定义类进行了测试。当我调用pop 时,它自动调用了我没想到的析构函数。我强硬pop 只会删除指向该自定义类的指针,我必须在调用 pop 之前删除指针。谁能证实我的发现?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 2010-10-04
      • 1970-01-01
      • 2013-11-21
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多