集合中的不可变对象(C++ 和 Qt)

Immutable object in collections (C++ and Qt)

本文关键字:C++ Qt 对象 不可变 集合      更新时间:2023-10-16

我坚持使用不可变对象和集合。假设我有以下类:

 //in .h
 class Data {
 public:
      Data(const DataObj& data);
      Data(const Data&);
      const DataObj& getDataObj() const;
 private:
      const DataObj _data; //actually several objects or simple type
 }
 inline const DataObj& Data::getDataObj() const {return _data};
 //in .c
 Data(const DataObj& data)  : _data(data){}; 
 Data(const Data& original) : _data(original._data){}

问题是当我想使用集合时,我遇到了错误

   in member function Data&Data::operator(const Data&);
   instantiation from 'typename QMap<Key,T>::iterator QMap<Key, T>::insert(const Key&, const T&)[with Key = int, T = Data]'
   instantiation from here
   error : non-static const member 'const DataObj Data::_data', can't use default assignment operator

现在定义赋值运算符似乎没有意义,因为它的原型将是

 Data& operator=(const Data&);

我该怎么办?我是否被迫删除所有常量限定符才能在集合中使用我的类?还是使用指针?

如果您像这样实例化地图

QMap <MyKey, Data> 

我想您应该始终为数据定义一个赋值运算符(默认或您自己的)。

您应该尝试使用指针,如您所建议的,如下所示

QMap <Mykey, Data*> 
QMap <Mykey, QSharedPointer<Data>> 

如果您查看 QMap 代码 http://code.woboq.org/kde/include/QtCore/qmap.h.html,某些运算符/成员返回 ,因此需要定义赋值。

使用好的stl容器而不是坏的Qt

由于 COW,这将无法与Qt容器一起使用,但它可以使用stl(直到您尝试复制容器)

class C
{
    C operator=(const C&);
};
int main()
{
    std::map<int, C> cc;
    cc.insert(std::make_pair(0, C()));
}

您可以将数据成员设置为非常量,但仅向类的用户提供 const 访问权限,赋值运算符除外:

class Data {
 public:
      Data(const DataObj& data);
      Data(const Data&);
      Data& operator=(const Data&);
      const DataObj& getDataObj() const;
 private:
      DataObj _data;
 };

这样,赋值是唯一可以改变现有对象的操作。然后,您必须确保在任何公共接口中提供对这种类型的 const 实例的访问。