【问题标题】:In C++, I want to return an array of objects from a function and use it in another在 C++ 中,我想从一个函数返回一个对象数组并在另一个函数中使用它
【发布时间】:2011-10-13 01:53:52
【问题描述】:

作为我正在学习 Qt 的一个小项目的一部分,我试图通过一个函数返回一个对象数组。然后我想正确检索这个数组并使用它的内容。现在,我只打印单个属性的几个值来尝试使其工作。

我遇到的问题是,当我尝试打印其内容时,只有数组中的第一项具有正确的值(其余的似乎是随机位模式)。

这里是返回函数:

QLine* LinesData::getList(){

  QLine *lineList2[50];
  for(int i = 0; i < 50; i++){
      lineList2[i] = new QLine(10, 10 * i, 100, 100);
  }

return *lineList2;}

这是尝试使用它的函数:

void runtimeWindow::drawAllLines(){
  QLine* lines = linesData.getList();
  for(int i = 0; i < 5; i++){
      qDebug() << lines[i].x1();
  }
}

【问题讨论】:

    标签: c++ arrays qt object


    【解决方案1】:

    使用std::vectorstd:shared_ptr 如下:

      std::vector<std::shared_ptr<QLine> >  LinesData::getList(){
    
      std::vector<std::shared_ptr<QLine> > lineList2;
      for(int i = 0; i < 50; ++i){
          lineList2.push_back(new QLine(10, 10*i, 100, 100));
      }
    
      return lineList2;}
    

    void runtimeWindow::drawAllLines(){
      std::vector<std::shared_ptr<QLine> > lines = linesData.getList();
      for(auto i = lines.begin(); i != lines.end(); ++i){
          qDebug() << (*i)->x1();
      }
    }
    

    如果您的编译器中没有 std::shared_ptr,请使用 boost 版本。

    使用std::vector 容器可以避免与 C 风格相关的问题(例如缓冲区溢出),std::shared_ptr 会在您处理完向量的内容后执行一种垃圾收集,以帮助防止内存泄漏。

    您也可以通过执行以下操作完全不使用指针来执行此操作:

      std::vector<QLine> LinesData::getList(){
    
      std::vector<QLine> lineList2(50);
      for(int i = 0; i < 50; ++i){
          lineList2[i].setLine(10, 10*i, 100, 100);
      }
    
      return lineList2;}
    

    然后使用

    绘制它们
    void runtimeWindow::drawAllLines(){
      std::vector<QLine> lines = linesData.getList();
      for(auto i = lines.begin(); i != lines.end(); ++i){
          qDebug() << i->x1();
      }
    }
    

    【讨论】:

    • @Ben Voigt:我倾向于按照我想到的顺序来写。我想这只是意味着我倒退了。
    • 值得注意的是,他已经在使用 Qt。因此,QList 似乎是合乎逻辑的选择(因为它也已经被隐式共享等等)。
    • 只为美的类型名:typedef std::shared_ptr QLinePtr;并且你可以在 Qt 中使用 QList 和 QSharedPointer。
    【解决方案2】:

    由于您没有连续分配数据,您将无法使用指针算法(包括数组下标运算符)来查找其他元素。

    您也忘记了释放数据。这不是 Java,内存不会自行释放。

    最好只使用std::vector&lt;QLine&gt;。 Qt 还提供了一些可以工作的容器。

    【讨论】:

    • 数据(QLine*)是连续的,他错误地取消了lineList2的引用。
    • @Ozan:对象不连续。他有一个指针数组,而不是QLine 的数组。
    • 我以为他打算返回数组
    【解决方案3】:
    QLine *lineList2[50];
    

    lineList2 是一个指针数组。它们是连续的,但它们指向的内存位置可能不是。所以,

    return *lineList2;
    

    您正在返回对序列中第一个对象的引用。但是根据它的地址,您无法使用 [] 运算符访问其他对象。实际上你需要做的是 -

    QLine** LinesData::getList(){
        // .....
    
        return lineList2;
    }
    
    void runtimeWindow::drawAllLines(){
      QLine** lines = linesData.getList();
      for(int i = 0; i < 5; i++){
          qDebug() << *(lines[i]).x1(); // or lines[i]->x1();
      }
    }
    

    或者简单地使用std::vector,就像@Ben 建议的那样避免所有这些痛苦。

    【讨论】:

      【解决方案4】:

      您正在返回取消引用的 lineList2,它是第一个 QLine* 指针,您可以使用 lines[0] 访问它。但随后lines[1]等不是对数组进行操作,而是对第一个QLine*指针进行操作。

      1st:使用容器,例如 std::vector

      第二个:当调用函数在使用后没有销毁对象时,同时返回一个堆对象并转移所有权容易发生内存泄漏。您可以修改 getlist() 使其期望并填充一个容器,而不是创建它:

      void LinesData::getQlines(std::vector<QLine>& lineList2)
      {
        for(int i = 0; i < 50; i++)
            lineList2.push_back(QLine(10, 10*i, 100, 100));
      }
      

      第三:当你转移堆对象的所有权时,使用像 shared_ptr 这样的智能指针

      【讨论】:

        【解决方案5】:

        使用

        std::vector<QLine>
        

        new QLine[50]
        

        然后返回那个指针。调用者负责释放这个指针。

        【讨论】:

        • 顺便说一句,我认识你吗?格伦伊格尔?
        猜你喜欢
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-30
        • 2013-11-14
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        相关资源
        最近更新 更多