D
D
Daniel Demidko2018-02-17 04:30:12
C++ / C#
Daniel Demidko, 2018-02-17 04:30:12

Is this code correct?

I know for sure that this code is incorrect, because it returns a reference to a temporary object

// Возвращает ссылку на несуществующее значение
const std::string &getLink() {
    // Объект будет уничтожен при выходе из функции
    std::string tmpObject;
   // Возвращаем ссылку на него
   return tmpObject;
}

But I can't say the same about this code:
// Вроде бы тоже самое что и в предыдущем примере
const std::string &link = std::string("test");
// Но у меня есть сомнения

Who can explain to me the fundamental difference between these two examples?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim Moseychuk, 2018-02-17
@DanielDemidko

In the first case, your object is destroyed before the reference.
In the second case, the lifetime of the reference and the object is the same, so this is a working example.
There are no temporary objects. There is a stack and there is a heap. Understanding the difference between these two areas of memory answers 90% of the questions in C++.

A
Ariox41, 2018-02-17
@Ariox41

The standard has a rule that when you create a constant reference to an automatically managed object, its lifetime is extended to the lifetime of the constant reference. However, this does not apply to the return statement and there is a special rule for initialization lists (read more here ). Accordingly, in the following example, the getRef function is incorrect, but the foo function is implemented correctly.

const std::string &getRef() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    const std::string& ref = getRef();
    std::cout << ref; // Выведет 123
}

In any case, using this approach does not make sense - you can just rely on the return value optimization and write like this:
std::string getStr() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    std::string str = getStr();
    std::cout << str; // Выведет 123
}

// На крайний случай можно так - это точно корректно, но лучше не нужно - иначе кто-нибудь 
// может случайно удалить const, что приведёт к проблемам. 
void bar(){
    const std::string& ref = getStr();
    std::cout << ref; // Выведет 123
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question