问题描述
我正在解决一个问题,我有某种定制的“容器”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;
}
main.cpp:21:24: error: cannot initialize return object of type 'MyItem *' with an rvalue of type 'const MyItem *'
我的函数需要返回一个非常量的值,因为调用者需要修改检索到的对象。有没有办法来解决这个问题?这是避免析构函数并向调用者指示返回值为空的最佳解决方案吗。
我知道有几种方法可以做到这一点:
解决方法
返回指向 QList 存储中的内存地址的指针是不明智的。从 QList 文档中“请注意,在 QList 上执行的任何非常量函数调用都会使所有现有的迭代器未定义”。如果内部容器存储了实际的指针,那么这将不是问题。这些甚至可以是无需编写析构函数的智能指针。
但是我也看到您通过值传递来添加项目。如果按值传递在那里是可以接受的,那么为什么不返回呢?这是一个不一致的界面。
听起来你真的想通过引用传递和返回,例如add(const MyItem&)
和 MyItem& get(int)
。
如 rafix 所述,QList 的 operator[](idx)
返回一个非常量引用,因此您可以简单地返回该引用。
那你将如何进行边界检查?有多种方法,但最简单的方法是添加一个 size()
方法。