开发者

In C++, I want to return an array of objects from a function and use it in another

开发者 https://www.devze.com 2023-04-12 11:37 出处:网络
As part of a small project I\'m doing to learn Qt, I\'m trying to return an array of objects through a function.I then want to retrieve this array properly 开发者_StackOverflow中文版and use it\'s cont

As part of a small project I'm doing to learn Qt, I'm trying to return an array of objects through a function. I then want to retrieve this array properly 开发者_StackOverflow中文版and use it's content. Right now, I only print a couple values of a single attribute to try and make it work.

The problem I have is that when I try to print its content, only the first item in the array holds the proper value (the rest seem to be random bit patterns).

Here is the return function:

QLine* LinesData::getList(){

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

return *lineList2;}

And here is the function that attempts to use it:

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


Use std::vector and std:shared_ptr as in:

  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;}

and

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

If you don't have std::shared_ptr in your compiler, use the boost version.

Use of the std::vector container avoids problems associated with C style (e.g. buffer overflow) and std::shared_ptr performs a kind of garbage collection when you're done with the content of the vector to help prevent memory leaks.

You can also do this without pointers at all by doing the following:

  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;}

and then draw them using

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


Since you haven't allocated your data contiguously, you won't be able to use pointer arithmetic (which includes the array subscript operator) to find the other elements.

You also are forgetting to free the data. This isn't Java, memory won't deallocate itself.

It would be best to just use std::vector<QLine> for this. Qt also provides some containers that could work.


QLine *lineList2[50];

lineList2 is an array of pointers. They are contiguous but the memory locations they are pointing at might not be. So,

return *lineList2;

You are returning the reference to first object in the sequence. But based on it's address you cannot access the other objects using [] operator. What actually you need to do is -

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();
  }
}

Or simply use std::vector which keeps away from all these pain as @Ben suggested.


You are returning the dereferenced lineList2, which is the first QLine* pointer, which you can access with lines[0]. But then lines[1] and so on is not operating on the array but the first QLine* pointer.

1st: Use containers, like std::vector

2nd: returning a heap object and transferring ownership at the same time is prone to memory leaks when a calling function does not destroy the object after use. You can modify getlist() so that it expects and populates a container instead of creating it:

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

3rd: when you are transferring ownership of heap objects use smart pointers like shared_ptr


Use

std::vector<QLine>

or

new QLine[50]

then return that pointer. The caller is responsible for freeing this pointer.

0

精彩评论

暂无评论...
验证码 换一张
取 消