Я застрял с использованием неизменных объектов с коллекциями. Предположим, у меня есть следующий класс:
//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&);
Что я должен делать? Я вынужден удалить все постоянные квалификаторы, чтобы использовать мой класс внутри коллекций? Или использовать указатели?
Используйте хорошо stl
контейнеры вместо плохих Qt
:
Это не будет работать с Qt
контейнер из-за COW, но это нормально (пока вы не попытаетесь скопировать контейнер) с stl
class C
{
C operator=(const C&);
};
int main()
{
std::map<int, C> cc;
cc.insert(std::make_pair(0, C()));
}
Если вы создаете свою карту, как эта
QMap <MyKey, Data>
Я думаю, вы всегда должны определять оператор присваивания для данных (по умолчанию или ваш собственный).
Вы должны попробовать использовать указатели, как вы предлагаете, вот так
QMap <Mykey, Data*>
QMap <Mykey, QSharedPointer<Data>>
Если вы посмотрите на код QMap http://code.woboq.org/kde/include/QtCore/qmap.h.html, некоторые операторы / члены возвращаются < T>, так что это нужно будет определить назначение.
Вы можете сделать элемент данных неконстантным, но предоставить только константный доступ пользователям класса, за исключением оператора присваивания:
class Data {
public:
Data(const DataObj& data);
Data(const Data&);
Data& operator=(const Data&);
const DataObj& getDataObj() const;
private:
DataObj _data;
};
Таким образом, присваивание является единственной операцией, которая может изменить существующий объект. Затем вам необходимо убедиться, что вы предоставляете доступ к экземплярам const этого типа в любых открытых интерфейсах.