2011-09-30 1 views
4

У меня есть класс MyClass, содержащий некоторые данные, хранящиеся в std::map s. Стандартные карты содержат указатели на объекты, например.Expose Member Data Through Iterator только для чтения

private: 
    std::map<int,Object*> m_data; 

Я хочу выставить данные во внешний мир, но я не хочу, чтобы другие классы/функции, чтобы иметь возможность изменять либо (I) карту m_data или (б) объекты, на который указывает значения в m_data. Мне нужна какая-то гипотетическая функция, скажем getDataBegin(), которая возвращает итератор по данным, имеющим свойства выше. Например, я хочу следующие псевдо-код примеров на провал:

iterator_type itr = myclass.getDataBegin(); 
erase(itr); // not allowed because we cannot modify m_data; 
itr.second = NULL; // not allowed to change content of m_data (falls under first rule) 
itr.second->methodWithSideEffect(); // not allowed because changes content of object pointed to. 

Короче говоря, можно сказать, я после того, как доступ только для чтения к некоторым данным членов. Это вообще возможно в хорошем смысле, и если да, то как я могу это сделать?

+1

Нет бесплатной функции 'erase()', так как пока вы не выставляете ссылки на неконстантные ссылки на ваш контейнер, вам не о чем беспокоиться. Если вы создадите сопоставленный тип 'const Object *', то никто не сможет изменить и указателей. Если изменение отображаемого типа не является вариантом, возможно, что-то можно сделать с помощью 'transform_iterator', который будет содержать указатели. –

+0

Проблема в моей таблице 'MyClass' Мне нужна карта ' not 'map ' и компиляторы (g ++/icc) не кажутся счастливыми в том, что они касты между ними. – Dan

+0

Как насчет 'map ', хотя? –

ответ

2

Попробуйте разоблачить повышение transform_iterator обернуто вокруг карты const_iterator. Функция преобразования должна быть чем-то вроде

[](const pair<int, object*>& x) 
{ 
    return make_pair(x.first, const_cast<const object*>(x.second)); 
} 
+0

Абсолютно никакой необходимости в 'const_cast' здесь. – Puppy

+0

@DeadMG Что бы вы использовали тогда? – Ayjay

+0

@Ayjay: Он может ссылаться на использование 'std :: pair' ctor, где вы явно должны предоставить аргументы шаблона. Я не вижу вреда в использовании 'const_cast' для _add_' const', но я, вероятно, использовал бы 'std :: pair', потому что мне кажется, что это менее запутанно, чем использование шаблона функции, чтобы не было необходимости описывать типы и затем явным образом, чтобы компенсировать это ... – sbi

0

return const_iterator, const_iterator допускает доступ только для чтения.

std::map<int,Object*>::const_iterator const getDataBegin(); 
+0

1) 'const_iterator' делает указатель объекта' Object * const', а не 'const Object *' - вы можете изменить Object, но не указатель. 2) Предполагая, что мы получаем карту, мы должны передать 'const_iterator' метод' erase' (зафиксированный в C++ 11). – UncleBens

+0

Неверный ответ, нарушает правило (ii). –