【问题标题】:Qt C++11 Handing out raw pointer from QListQt C++11 从 QList 分发原始指针
【发布时间】:2021-05-30 17:41:23
【问题描述】:

我正在解决一个问题,我有某种定制的“容器”DTO,其中包含一系列项目。该类的用户应该能够从容器中的某个位置检索项目。我希望容器不保留对其包含的项目的原始指针的引用,而是真正拥有它们,因此不需要自定义析构函数。这是我想出的:

#include <QList>

class MyItem {

public:
    MyItem(int n) : number(n){}

private:
    int number;
};

class MyContainer {

public:
    void addItem(MyItem item){
        m_items.append(item);
    }

    MyItem* getItemAt(int pos){
           if(pos < m_items.size() && pos >= 0){
                return &(m_items.at(pos));
           }
           return nullptr;
    }

private:
    QList<MyItem> m_items;

};


int main(){

    MyContainer container;

    MyItem item1(4);
    container.addItem(item1);

    MyItem* item_ptr = container.getItemAt(0);
    return 0;
}

getItemAt 函数的返回中,我收到了这个错误:

main.cpp:21:24: error: cannot initialize return object of type 'MyItem *' with an rvalue of type 'const MyItem *'

我的函数需要返回一个非 const 值,因为调用者需要修改检索到的对象。有没有办法来解决这个问题?这是避免析构函数并向调用者指示返回值为空的最佳解决方案吗?

我知道有几种方法可以做到这一点:

  • 返回一个可选的:不幸的是我绑定到 C++11 所以不是一个选项
  • 抛出异常:我真的不喜欢这个选项,因为代码库有 0 个异常 atm,我宁愿在这里不介绍它们。

【问题讨论】:

  • at(idx) 返回const T&amp;operator[](idx) 返回T&amp;,使用后者即可。
  • 还是出现上述错误。
  • “还是出现上面提到的错误”这不可能是真的。
  • 使用标准容器。不再有任何理由在不与现有 Qt API 接口的新代码中使用 QList。

标签: c++ qt c++11


【解决方案1】:

返回指向 QList 存储中的内存地址的指针是不明智的。从 QList 文档中“请注意,在 QList 上执行的任何非常量函数调用都会使所有现有的迭代器未定义”。如果内部容器存储了实际的指针,那么这将不是问题。这些甚至可以是无需编写析构函数的智能指针。

但是,我也看到您通过值传递来添加项目。如果按值传递在那里是可以接受的,那么为什么不返回呢?这是一个不一致的界面。

听起来你真的想通过引用传递和返回,例如add(const MyItem&amp;)MyItem&amp; get(int)

正如 rafix 所述,QList 的 operator[](idx) 返回一个非 const 引用,因此您可以简单地返回它。

那么你将如何进行边界检查?有多种方法,但最简单的方法是添加一个size() 方法。

【讨论】:

  • 是的,我想要这种方法,但是参考不能为空,我需要以某种方式与调用者沟通,在 X 位置没有找到任何值。为此,我想使用 nullptr。
  • @Curunir 那么如果你绝对想坚持使用返回指针的接口,你最好的选择是将智能指针存储在 m_items 中。
猜你喜欢
  • 2019-06-30
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 2014-12-19
  • 2014-10-31
  • 1970-01-01
  • 2019-12-20
  • 2016-08-01
相关资源
最近更新 更多