Ну вот например, дана функция
const string &fncRef()
{
return "Hello, World!";
}
При попытке использовать следующий стейтмент:
cout<<fncRef()<<endl;
в консоль выводится пустота.
Если тип возврата поменять на числовой, то число выведется без проблем.
Заранее благодарю за ответы.
C/C++
[c++] Почему при возврате строки по ссылке(const), она не выводится в консоль? Подробности внизу.
Потому что взять адрес строкового литерала можно, а числового литерала нельзя.
auto as = &"Hello world!"; // так можно, потому что lvalue
auto an = &5; // так нельзя, потому что rvalue
lvalue от rvalue отличаются возможностью взятия адреса. Строковый литерал представлен в памяти массивом символов и у него имеется конкретный адрес в памяти. Имя массива является адресом на его первый элемент. Строковый литерал является анонимным массивом, под который в стеке, в области автоматической памяти выделяется память под указатель на первый элемент. Такой указатель относится к локальным переменным. После выхода кода из области видимости, в которой был созданы локальные переменные, память автоматически освобождается. Код теряет указатель, который связывал его с данными строкового литерала. Однако сами данные так и остаются хранится в памяти. Отсутствует возможность обратиться к ним. Числовой литерал является временным объектом в памяти и адреса не имеет. Следовательно, он не относится к области автоматической памяти и в данном случае освобождать нечего. Важно понимать, что он не только анонимный, но и безадресный. Это свойство и позволяет вернуть его по ссылке из локального контекста, автоматические объекты которого удалены. Однако и в этом случае вы получите от компилятора предупреждение о том, что предприняли попытку возвращения адреса временной переменной.
#include <iostream>
#include <string>
using namespace std;
const string str() {
return "Hello!"; // lvalue - только по значению
}
const int one() {
return 1; // rvalue - по значению
}
const int& two() {
return 2; // rvalue - по ссылке, с предупреждением о возвращении адреса временной переменной
}
const int&& three() {
return 3; // rvalue - путём перемещения, с предупреждением о возвращении адреса временной переменной
}
int main() {
cout
<< str() << '\n'
<< one() << '\n'
<< two() << '\n'
<< three() << '\n';
}
auto as = &"Hello world!"; // так можно, потому что lvalue
auto an = &5; // так нельзя, потому что rvalue
lvalue от rvalue отличаются возможностью взятия адреса. Строковый литерал представлен в памяти массивом символов и у него имеется конкретный адрес в памяти. Имя массива является адресом на его первый элемент. Строковый литерал является анонимным массивом, под который в стеке, в области автоматической памяти выделяется память под указатель на первый элемент. Такой указатель относится к локальным переменным. После выхода кода из области видимости, в которой был созданы локальные переменные, память автоматически освобождается. Код теряет указатель, который связывал его с данными строкового литерала. Однако сами данные так и остаются хранится в памяти. Отсутствует возможность обратиться к ним. Числовой литерал является временным объектом в памяти и адреса не имеет. Следовательно, он не относится к области автоматической памяти и в данном случае освобождать нечего. Важно понимать, что он не только анонимный, но и безадресный. Это свойство и позволяет вернуть его по ссылке из локального контекста, автоматические объекты которого удалены. Однако и в этом случае вы получите от компилятора предупреждение о том, что предприняли попытку возвращения адреса временной переменной.
#include <iostream>
#include <string>
using namespace std;
const string str() {
return "Hello!"; // lvalue - только по значению
}
const int one() {
return 1; // rvalue - по значению
}
const int& two() {
return 2; // rvalue - по ссылке, с предупреждением о возвращении адреса временной переменной
}
const int&& three() {
return 3; // rvalue - путём перемещения, с предупреждением о возвращении адреса временной переменной
}
int main() {
cout
<< str() << '\n'
<< one() << '\n'
<< two() << '\n'
<< three() << '\n';
}
потому что ты возвращаешь ссылку на локальный объект, локальные объекты уничтожаются после выхода из области видимости, из функции
Алексей Борисов
Но ведь с числами такого не происходит
Алексей Борисов
Нет, только что проверял.
Скорее всего эт потому что ты выводишь адрес константы. Сделай проще, я почти уверен, что можно использовать константы в сишном стиле. Сделай несколько вариантов этих констант, чтобы выводя их все со спецсимволами & и без них увидеть правильный вариант.
Похожие вопросы
- Как работает математика в C++ Почему (32-6)/100*20 = 0
- Подскажите, почему получается пустая строка и как это исправить.
- Что за числа выводятся при переполнении int в C++?
- Заполнить двумерный массив 5*3 и найти строку с максимальным произведением элементов. C++
- C++: "С-Строка" и ошибка
- Значение типа const char* нельзя присвоить сущности типа char*
- C++. Разница меджу #define и const ?
- Ошибка C2664: невозможно преобразовать аргумент 1 из "const char [6]" в "char *" в C ++
- Помогите написать код c++ со строками
- Ошибка с русскими символами в языке C++ программе xcode. Пропадает если указать большее количество элементов в строке.
https://www.onlinegdb.com/WUqIrKL1l
Тут работа с классами. В первом классе(A) есть string переменная, во втором классе(B) статическая функция initObject типа (A) с типом возврата по константной ссылке, потому что возвращается анонимный объект, а он rvalue.
Функция B::init() должна возвращать анонимный объект класса (A("Hello,World!"), который при создании активирует свой конструктор и таким образом инициализирует строку класса (A) соответствующим аргументом в виде строки "Hello,World!".
Но что самое интересное, что даже несмотря на то, что даны и значение по умолчанию и значение, которое нужно присвоить объекту, не выводится в консоль.