Все ваши примеры приводят к неопределенному поведению во время выполнения. Вы возвращаете указатели или ссылки на элементы, которые исчезают после выхода из функции.
Позвольте мне уточнить:
int * returnA()
{
static int a; // The static keyword keeps the variable from disappearing.
int * j = 0; // Declare a pointer to an int and initialize to location 0.
j = &a; // j now points to a.
return j; // return the location of the static variable (evil).
}
В вашей функции переменная j
назначена для указания на временное местоположение a
. При выходе из вашей функции переменная a
исчезает, но ее прежнее местоположение возвращается через j
. Поскольку a
больше не существует в месте, указанном j
, при доступе к *j
произойдет неопределенное поведение.
Переменные внутри функций не должны изменяться с помощью ссылки или указателя другим кодом. Это может произойти, хотя это приводит к неопределенному поведению.
Будучи педантичным, возвращаемые указатели должны быть объявлены как указывающие на постоянные данные. Возвращенные ссылки должны быть константными:
const char * Hello()
{
static const char text[] = "Hello";
return text;
}
Вышеуказанная функция возвращает указатель на постоянные данные. Другой код может получить доступ (прочитать) к статическим данным, но не может быть изменен.
const unsigned int& Counter()
{
static unsigned int value = 0;
value = value + 1;
return value;
}
В приведенной выше функции value
инициализируется в ноль при первой записи. Все последующие исполнения этой функции приводят к увеличению value
на единицу. Функция возвращает ссылку на постоянное значение. Это означает, что другие функции могут использовать значение (издалека), как если бы оно было переменной (без разыменования указателя).
В моем мышлении указатель используется для необязательного параметра или объекта. Ссылка передается, когда объект должен существовать. Внутри функции ссылочный параметр означает, что значение существует, однако указатель должен быть проверен на нулевое значение перед разыменованием его. Кроме того, со ссылкой, есть дополнительная гарантия, что целевой объект является действительным. Указатель может указывать на неверный адрес (не ноль) и вызывать неопределенное поведение.