Программирование. Принципы и практика использования C++ Исправленное издание, стр. 224
int* pi = new int; // выделяем память для одной переменной intint* qi = new int[4]; // выделяем память для четырех переменных int // (массив)double* pd = new double; // выделяем память для одной переменной // doubledouble* qd = new double[n]; // выделяем память для n переменных // doubleОбратите внимание на то, что количество объектов может задаваться переменной. Это важно, поскольку позволяет нам выбирать, сколько массивов можно разместить в ходе выполнения программы. Если
n2
Указатели на объекты разных типов имеют разные типы. Рассмотрим пример.
pi = pd; // ошибка: нельзя присвоить указатель double* указателю int*pd = pi; // ошибка: нельзя присвоить указатель int* указателю double*Почему нельзя? В конце концов, мы же можем присвоить переменную типа
intdouble[]qi[2]intqi[0]qd[2]doubleqd[0]intdoubleqiqdЭто объяснение с практической точки зрения. С теоретической точки зрения ответ таков: присваивание друг другу указателей на разные типы сделало бы возможными ошибки типа (type errors).
17.4.2. Доступ с помощью указателей
Кроме оператора разыменования
*[]double* p = new double[4]; // выделяем память для четырех переменных // типа double в свободной памятиdouble x = *p; // читаем (первый) объект, на который // ссылается pdouble y = p[2]; // читаем третий объект, на который // ссылается pТак же как и в классе
vectorp[2]p[0]p[0]*p[]**p = 7.7; // записываем число в (первый) объект, на который // ссылается pp[2] = 9.9; // записываем число в третий объект, на который // ссылается pУказатель ссылается на объект, расположенный в памяти. Оператор разыменования (“contents of” operator, or dereference operator) позволяет читать и записывать объект, на который ссылается указатель
pdouble x = *p; // читаем объект, на который ссылается указатель p*p = 8.9; // записываем объект, на который ссылается указатель pКогда оператор
[]ppdouble x = p[3]; // читаем четвертый объект, на который ссылается pp[3] = 4.4; // записываем четвертый объект, на который // ссылается pdouble y = p[0]; // p[0] - то же самое, что и *pВот и все. Здесь нет никаких проверок, никакой тонкой реализации — простой доступ к памяти.

Именно такой простой и оптимально эффективный механизм доступа к памяти нам нужен для реализации класса
vector17.4.3. Диапазоны
double* pd = new double[3];pd[2] = 2.2;pd[4] = 4.4;pd[– 3] = – 3.3;
pdpd[2]pd[4]pdpd[–3]doublepd