// НЕ БУДЕТ КОМПИЛИРОВАТЬСЯ
ptr->setX(4.0);
*ptr = Point2D(4.0, 4.5);
Константный указатель
Указатели могут использоваться со встроенными типами так же, как с классами. Используемый в выражении унарный оператор
int i = 10;
int j = 20;
int *p = &i
int *q = &j
cout << *p << " equals 10" << endl;
cout << *q << " equals 20" << endl;
*p = 40;
cout << i << " equals 40" << endl;
p = q;
*p = 100;
cout << i << " equals 40" << endl;
cout << j << " equals 100" << endl;
Оператор
Указатели имели плохую репутацию в С и С++, причем доходило до того, что рекламировалось отсутствие указателей в языке Java. На самом деле указатели С++ концептуально аналогичны ссылкам в Java и C#, за исключением того, что указатели можно использовать для прохода по памяти, как мы это увидим позже в данном разделе. Более того, включение в Qt классов—контейнеров, использующих метод «копирования при записи» вместе со способностью С++ инстанцировать любой класс в стеке, означает возможность во многих случаях обойтись без указателей.
Ссылки
Кроме указателей С++ поддерживает также концепцию «ссылки». Подобно указателю, ссылка в С++ хранит адрес объекта. Основными отличиями являются следующие:
• Объявляются ссылки с применением оператора
• Ссылка должна быть инициализирована и не может в дальнейшем изменяться.
• С помощью ссылки обеспечивается прямое обращение к объекту; не предусмотрен специальный синтаксис, подобный операторам
• Ссылка не может быть нулевой.
Ссылки в основном используются при объявлении параметров. По умолчанию в С++ используется передача параметров по значению, т.е. при передаче параметров функции последняя получает в действительности новую копию объекта. Ниже приводится определение функции, которая получает параметры, передаваемые по значению.
#include
using namespace std;
double manhattanDistance(Point2D a, Point2D b)
{
return abs(b.x - a.x) + abs(b.y - a.y);
}
Эта функция может вызываться следующим образом:
Point2D harlem(77.5, 50.0);
Point2D broadway(12.5, 40.0);
double distance = manhattanDistance(broadway, harlem);
Опытные С—программисты избегают операций копирования путем объявления параметров в виде указателей вместо значений:
double manhattanDistance(const Point2D *ap, const Point2D *bp)
{
return abs(bp->x - ap->x) + abs(bp->y - ap->y);
}
После этого при вызове функции должны передаваться адреса вместо значений:
Point2D harlem(77.5, 50.0);
Point2D broadway(12.5, 40.0);
double distance = manhattanDistance(&broadway, &harlem);
Ссылки введены в С++ для того, чтобы сделать синтаксис менее громоздким и чтобы предотвратить передачу нулевого указателя. Если вместо указателей использовать ссылки, функция будет иметь следующий вид:
double manhattanDistance(const Point2D &a, const Point2D &b)
{
return abs(b.x - a.x) + abs(b.y - a.y);
}