2010-10-02 2 views
0

У меня есть этот код, который пытается защитить пользователя от ошибок границ массива.Проблема с изменением константного массива C++

Я не понимаю, почему это скомпилируется, потому что я объявил массив const, поэтому я должен получить ошибку компиляции!

спасибо большое.

/************ file: SafeAccessArray.h ********************/ 
template<typename T> 
class SafeAccessArray 
{ 
private: 
int _len; 
T * _arr; 
public: 
SafeAccessArray (int len=2) : _len (len), _arr (new T [len]) {} 
~SafeAccessArray() { delete _arr; } 
T& operator [](int i) const 
{if (i < 0 || i >= _len) throw (-1); 
else return _arr[i]; } 
}; 
/************ end of file: SafeAccessArray.h *************/ 

/************ file: SafeAccessArray1.cpp *************/ 
#include "SafeAccessArray.h" 
int main()`enter code here` 
{ 
SafeAccessArray<int> intArr (2); 
intArr[0] = 0; 
intArr[1] = 1; 
const SafeAccessArray<int> intArrConst (2); // THIS IS THE "PROBLEMATIC" LINE 
intArrConst [0] = 0; 
intArrConst [1] = 1; 
return 0; 
} 
/************ end of file: SafeAccessArray1.cpp ******/ 
+3

'SafeAccessArray' нужен оператор копирования и оператор присваивания. Посмотрите на [Правило трех] (http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29) и идиома копирования и свопинга. Даже если это была хорошая идея, просто используйте 'std :: vector' в частном порядке и покончите с этим. Кроме того, не бросайте целые числа, бросайте вещи, происходящие из 'std :: exception'; 'std :: out_of_range' ждет. – GManNickG

+2

Пожалуйста, не бросайте '-1', даже в тестовый код. Throw ':: std :: out_of_range' или что-то еще, кроме простого базового типа, такого как' int' или 'char *', и предпочтительно что-то из ':: std :: exception'. – Omnifarious

+2

Кроме того, новый [] идет с удалением [], а не удаляется. – sellibitze

ответ

4

Да это const, но вы сделали T& operator [](int i) const в любом случае. Вы возвращаете ссылку, и эту функцию можно вызвать в объекте const.

Задать ему const T&. Еще лучше, остановитесь. Просто используйте std::vector и функцию at().

+0

Итак, просто, чтобы было ясно, когда я назову «intArrConst [0] = 0» - operator [] вызовет приведение к объекту, не являющемуся константой, или присваивание не произойдет на моем объекте const? – limlim

+0

@limlim: Что? Когда вы говорите 'intArrConst [0]', 'T & operator [] (int i) const' вызывается. Это приводит к 'T &', а затем вы назначаете 0 ему, изменяя ссылку (которая, будучи псевдонимом, просто меняет значение, это сглаживание.) – GManNickG

+1

@limlim: класс содержит 'T * _arr;' 'const 'экземпляр класса содержит' T * const _arr', тогда как вы хотите, чтобы он имел 'T const * const _arr'. C++ не добавлял дополнительную квалификацию, которую вы хотели, поэтому гарантия - ваша ответственность. – Potatoswatter

2

Я думаю, что operator[] функции члена желает следующих два перегруженных варианта:

T& operator [](int i); 
const T& operator [](int i) const; 

Обеспеченного одно

T& operator [](int i) const; 

не соответствует ни одному из указанных выше, и, следовательно, проблемы.

Смежные вопросы