简体   繁体   English

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

[英]Immutable object in collections (C++ and Qt)

I am stuck with using immutable objects with collections. 我坚持使用不可变对象与集合。 Let assume I have the following class : 假设我有以下课程:

 //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){}

The issue is that when I want to use collections, I have the error 问题是,当我想使用集合时,出现错误

   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

Now defining an assignment operator doesn't seems to make sense, since its prototype will be 现在定义赋值运算符似乎没有任何意义,因为其原型将是

 Data& operator=(const Data&);

What should I do? 我该怎么办? Am I forced to remove all constant qualifiers in order to use my class inside collections? 为了在集合中使用我的课程,我是否被迫删除所有常量限定词? Or use pointers? 还是使用指针?

If you are instantiating your map like this 如果您要像这样实例化地图

QMap <MyKey, Data> 

I guess you should always define an assignment operator for Data (default or your own). 我想您应该始终为Data定义一个赋值运算符(默认值或您自己的)。

You should try using pointers, as you suggest, like this 您应该像建议的那样尝试使用指针

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

If you take a look to the QMap code http://code.woboq.org/kde/include/QtCore/qmap.h.html , some operators/members return < T >, so it would need assignment defined. 如果您查看QMap代码http://code.woboq.org/kde/include/QtCore/qmap.h.html ,某些操作员/成员将返回<T>,因此需要定义分配。

You can make the data member non-const, but provide only const access to users of the class, except for the assignment operator: 您可以使数据成员为非const,但仅向类用户提供const访问,但赋值运算符除外:

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

In this way, assignment is the only operation that can mutate an existing object. 这样,赋值是唯一可以使现有对象发生变异的操作。 You would then have to make sure you provide access to const instances of this type in any public interfaces. 然后,您必须确保在任何公共接口中都提供对这种类型的const实例的访问。

Use good stl containers instead of bad Qt : 使用优质的stl容器代替不良的Qt

This will fail to work with Qt container due to COW, but it ok (until you try to copy the container) with stl 由于COW,这将无法用于Qt容器,但是使用stl可以(直到尝试复制容器)

class C
{
    C operator=(const C&);
};

int main()
{
    std::map<int, C> cc;
    cc.insert(std::make_pair(0, C()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM