C ++在函数中创建std :: list并通过参数返回

时间:2015-12-06 00:33:14

标签: c++ c++11

如何通过函数参数更正返回创建的std :: list?现在,我试试:

bool DatabaseHandler::tags(std::list<Tag> *tags)
{
    QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
    QSqlQueryModel model;
    model.setQuery(sql);

    if(model.lastError().type() != QSqlError::NoError) {
        log(sql);
        tags = NULL;
        return false;
    }

    const int count = model.rowCount();

    if(count > 0)
        tags = new std::list<Tag>(count);
    else
        tags = new std::list<Tag>();
//some code

    return true;
}

我可以使用它之后:

std::list<Tag> tags;
mDB->tags(&tags);

现在,我修复了我的功能:

bool DatabaseHandler::tags(std::list<Tag> **tags)
{
    QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
    QSqlQueryModel model;
    model.setQuery(sql);

    if(model.lastError().type() != QSqlError::NoError) {
        log(sql);
        *tags = NULL;
        return false;
    }

    const int count = model.rowCount();

    if(count > 0)
        *tags = new std::list<Tag>(count);
    else
        *tags = new std::list<Tag>();

    for(int i = 0; i < count; ++i) {
        auto record = model.record(i);
        Tag tag(record.value(Table::KEY_ID).toInt());
        (*tags)->push_back(tag);
    }

    return true;
}

它工作但列出返回大小4虽然循环只执行2次迭代和空子对象(如果我只是调用它们的默认构造函数)。 Tag类没有复制构造函数。

2 个答案:

答案 0 :(得分:2)

由于您已将已实例化的列表作为指向该函数的指针传递,因此无需创建另一个列表。 从这个意义上说,你的问题很不清楚。我建议你一般读一下指针,引用和函数调用。

http://www.cplusplus.com/doc/tutorial/pointers/ http://www.cplusplus.com/doc/tutorial/functions/

更新:我仍然强烈建议您阅读上述主题,因为您不了解这些基本要点。 无论如何,这是你可能想要做的事情(事件虽然我建议使用引用,这里是带指针的解决方案):

bool someFunc(std::list<Tag> **tags) {
    // by default null the output argument
    *tags = nullptr;
    if (error) {
        return false;
    }

    // dereference tags and assign it the address to a new instance of list<Tag>
    *tags = new std::list<Tag>();
    return true
}


std::list<Tag> *yourList;
if (someFunc(&yourList)) {
    // then yourList is valid
} else {
   // then you had an error and yourList == nullptr
}

但是,这不是惯用的C ++。请阅读现代书籍或教程。

答案 1 :(得分:1)

使用参考。

bool DatabaseHandler::tags(std::list<Tag>& tags);

std::list<Tag> tags;
mDB->tags(tags);

当然,您必须将所有->更改为.。在函数中对引用完成的每个操作都将对调用它的原始tags列表进行。

编辑:如果你想在函数内创建列表并返回它,你有几个选项。我认为最接近的是返回一个列表指针,如果函数失败则返回nullptr

//beware, pseudocode ahead
std::list<Tag>* DatabaseHandler::tags() //return new list
{
    if (success)
        return new std::list<Tag>(...); //construct with whatever
    else
        return nullptr; //null pointer return, didn't work
}

std::list<Tag> tags* = mDB->tags();

您也可以让它返回一个空列表,具体取决于您希望它如何工作。引用指针也会以相同的方式工作。

    bool DatabaseHandler::tags(std::list<Tag>*&); //return true/false

    std::list<Tag>* tags;
    mDB->tags(tags); //tags will be set to point to a list if it worked