Которые являются последствиями возврата значение как постоянная, ссылочная и постоянная ссылка в C++?

Вы можете выбрать свой предварительный профиль и связанный с ним сертификат из Подпись в Настройка сборки .

Проверьте прикрепленные скриншоты enter image description here на то же самое.

13
задан user96815 27 April 2009 в 23:29
поделиться

8 ответов

Ниже приведено описание всех ваших дел:

• Возврат по ссылке : вызов функции можно использовать в качестве левой части назначения. например, используя перегрузку оператора, если у вас перегружен operator [], вы можете сказать что-то вроде

a[i] = 7;

(при возврате по ссылке вы должны убедиться, что возвращаемый вами объект доступен после возврата: вы не должны возвращать ссылку на локальный или временный)

• Возвращать как постоянное значение : предотвращает использование функции в левой части выражения присваивания. Рассмотрим перегруженный оператор +. Можно написать что-то вроде:

a + b = c; // This isn't right

Наличие возвращаемого типа оператора + в качестве «const SomeType» позволяет возвращать по значению и в то же время предотвращает использование выражения в левой части присваивания.

Возврат в качестве постоянного значения также позволяет предотвратить опечатки, подобные этим:

if (someFunction() = 2)

, когда вы имели в виду

if (someFunction() == 2)

Если someFunction () объявлен как

const int someFunction()

, тогда описанная выше опечатка if () будет перехвачена компилятором.

• Возврат в качестве постоянной ссылки : этот вызов функции не может появляться с левой стороны назначения, и вы хотите избежать копирования (возврата по значению). Например, допустим, у нас есть класс Student, и мы хотели бы предоставить идентификатор доступа () для получения идентификатора студента:

class Student
{
    std::string id_;

public:

    const std::string& id() const;
};

const std::string& Student::id()
{
    return id_;
}

Рассмотрим средство доступа id (). Это должно быть объявлено как const, чтобы гарантировать, что функция-член id () не изменит состояние объекта. Теперь рассмотрим тип возвращаемого значения. Если бы возвращаемый тип был строковым, то можно написать что-то вроде:

Student s;
s.id() = "newId";

, что не то, что мы хотим.

Мы могли бы вернуть по значению, но в этом случае возврат по ссылке более эффективен. Делая возвращаемый тип константной строкой и дополнительно предотвращает изменение идентификатора.

27
ответ дан 1 December 2019 в 19:23
поделиться

Основная вещь, которую нужно понять, это то, что возвращение по значению создаст новую копию вашего объекта. Возврат по ссылке вернет ссылку на существующий объект. ПРИМЕЧАНИЕ: так же, как указатели, вы можете иметь висячие ссылки. Поэтому не создавайте объект в функции и не возвращайте ссылку на объект - он будет уничтожен при возврате из функции и возвратит висячую ссылку.

Возврат по значению:

  • Когда у вас есть POD (Обычные старые данные)
  • Когда вы хотите вернуть копию объекта

Возврат по ссылке:

  • Если у вас есть причина производительности, чтобы избежать копирования объекта, который вы возвращаете, и вы понимаете время жизни объекта
  • Когда вы должны вернуть конкретный экземпляр объекта, и вы понимаете время жизни объекта

Ссылки Const / Constant помогают вам обеспечить выполнение контрактов вашего кода и помогают компиляторам ваших пользователей находить ошибки использования. Они не влияют на производительность.

6
ответ дан 1 December 2019 в 19:23
поделиться

Возвращение постоянного значения не очень распространенная идиома, так как вы в любом случае возвращаете новую вещь, которую может иметь только вызывающий объект, поэтому нередко бывает, что они могут ' изменить это. В вашем примере вы не знаете, что они собираются с ним делать, так почему вы должны помешать им изменить его?

Обратите внимание, что в C ++, если вы не говорите, что что-то является ссылкой или указателем, это значение, поэтому вы будете создавать его новую копию, а не изменять исходный объект. Это может быть не совсем очевидно, если вы пришли из других языков, которые используют ссылки по умолчанию.

Возврат ссылки или константной ссылки означает, что это фактически другой объект в другом месте, поэтому любые изменения в нем будут влиять на этот другой объект.

1
ответ дан 1 December 2019 в 19:23
поделиться
  • Возврат по ссылке .

Вы можете вернуть ссылку на какое-то значение, например на член класса. Таким образом, вы не создаете копии. Однако вы не должны возвращать ссылки на значения в стеке, так как это приводит к неопределенному поведению.

#include <iostream>                                                                                                                                          
using namespace  std;


class A{
private: int a;

public:
        A(int num):a(num){}

        //a to the power of 4.
        int& operate(){
                this->a*=this->a;
                this->a*=this->a;
                return this->a;
        }

        //return constant copy of a.
        const int constA(){return this->a;}

        //return copy of a.
        int getA(){return this->a;}
};

int main(){

        A obj(3);
        cout <<"a "<<obj.getA()<<endl;
        int& b=obj.operate(); //obj.operate() returns a reference!

        cout<<"a^4 "<<obj.getA()<<endl;
        b++;
        cout<<"modified by b: "<<obj.getA()<<endl;
        return 0;
}

b и obj.a «указывают» на одно и то же значение, поэтому изменение b изменяет значение obj.a.

$./a.out 
a 3
a^4 81
modified by b: 82
  • Возвращает значение const .

С другой стороны, возвращение значения const указывает, что указанное значение нельзя изменить. Следует отметить, что возвращаемое значение является копией. Например,

constA()++;

приведет к ошибке компиляции, поскольку копия, возвращаемая constA (), является константой. Но это всего лишь копия, это не значит, что A :: a является константой.

  • Возвращает константную ссылку .

Это похоже на возврат константного значения, за исключением того, что ни одна копия не возвращается, но ссылка на фактический член. Однако его нельзя изменить.

const int& refA(){return this->a;}

const int& b = obj.refA();
b++;

приведет к ошибке компиляции.

1
ответ дан 1 December 2019 в 19:23
поделиться

Ваш первый случай:

const int exampleOne();

С простыми типами, такими как int, это почти никогда не то, что вы хотите, потому что const не имеет смысла. Возвращение по значению подразумевает копию, и вы можете свободно назначать неконстантный объект:

int a = exampleOne(); // perfectly valid.

Когда я вижу это, обычно потому, что тот, кто написал код, пытался быть константно-корректным, что похвально, но не вполне понимаю смысл того, что они писали. Однако есть случаи с перегруженными операторами и пользовательскими типами, в которых это может иметь значение.

Некоторые компиляторы (более новые GCC, Metrowerks и т. Д.) Предупреждают о поведении, подобном этому, с простыми типами, поэтому это должно быть избегать.

0
ответ дан 1 December 2019 в 19:23
поделиться
const int exampleOne();

Возвращает const копию некоторого int. То есть вы создаете новый int, который не может быть изменен. Это не очень полезно в большинстве случаев, потому что вы все равно создаете копию, поэтому вам, как правило, все равно, будет ли она изменена. Так почему бы просто не вернуть обычный int?

Это может иметь значение для более сложных типов, хотя их изменение может иметь нежелательные побочные эффекты. (Концептуально, скажем, функция возвращает объект, представляющий дескриптор файла. Если этот дескриптор является const, файл доступен только для чтения, в противном случае его можно изменить. Тогда в некоторых случаях имеет смысл для функции возвращать значение const. Но в целом возвращение значения const редко.

int& exampleTwo();

Этот возвращает ссылку на int. Это не влияет на время жизни этого значения, так что это может привести к неопределенному поведению в таком случае:

int& exampleTwo() {
  int x = 42;
  return x;
}

мы возвращаем ссылку на значение, которого больше не существует. Компилятор может предупредить вас об этом, но, вероятно, все равно скомпилируется. Но это бессмысленно и рано или поздно приведет к неожиданным сбоям. Это часто используется в других случаях, хотя. Если бы функция была членом класса, она могла бы вернуть ссылку на переменную-член, чье время жизни продолжалось бы до тех пор, пока объект не выйдет из области видимости, что означает, что возвращаемое значение функции все еще остается действительным, когда функция возвращается. То же, что и выше, возвращая ссылку на какое-то значение, не вступая во владение им и не влияя на его срок службы Основное отличие состоит в том, что теперь вы возвращаете ссылку на постоянный (неизменяемый) объект. В отличие от первого случая, это чаще всего полезно, так как мы мы больше не имеем дело с копией, о которой никто не знает, и поэтому модификации могут быть видны другим частям кода. (у вас может быть объект, который не является const, где он определен, и функция, которая позволяет другим частям кода получать доступ к нему как const, возвращая ссылку на него const.

1
ответ дан 1 December 2019 в 19:23
поделиться

В качестве альтернативы вы можете прочитать статью Девять параметров для управления постоянным состоянием пользователя в приложении ASP.NET .

В статьях автор объясняет плюсы и минусы каждого метода.

Из резюме:

ASP.NET предоставляет много разных способов сохранять данные между запросами пользователей. Вы можете использовать объект приложения, куки, скрытые поля, сеанс или Кэшировать объекты и многое другое методы. Решая, когда использовать каждый из иногда это может быть сложно. это статья представит вышеупомянутые методы и настоящее некоторые рекомендации о том, когда их использовать. Хотя многие из этих методов существовал в классическом ASP, лучшие практики когда их использовать изменилось с введение .NET Фреймворк. Чтобы сохранить данные в ASP.NET, вам придется скорректировать то, что вы узнали ранее о состоянии обработки в

  • Уверение компилятора в том, что определенный метод не изменяет объект

Если у вас есть класс и некоторые методы, которые «получают» или «получают» информацию из переменных экземпляра, не изменяя их, то я должен иметь возможность использовать их, даже если используется ключевое слово const. Например:

class MyObject
{
    ...
public:
    void setValue(int);
    int getValue() const; // The const at the end is the key
};

void funct(const MyObject &o)
{
    int val = o.getValue(); // Will compile.
    a.setValue(val); // Won't compile.
}
  • Наконец, (ваш случай) возвращает константное значение

Это означает, что возвращаемый объект не может быть изменен или изменен напрямую. Например:

const MyObject func();

void func2()
{
    int val = func()->getValue(); // Will compile.
    func()->setValue(val); // Won't compile.
    MyObject o1 = func(); // Won't compile.
    MyObject o2 = const_cast<MyObject>(func()); // Will compile.
}

Дополнительная информация о ключевом слове const: C ++ Faq Lite - Const Correctness

Относительно ссылок

Возврат или получение ссылки означает, что объект не будет продублирован. Это означает, что любое изменение, внесенное в само значение, будет отражено за пределами области действия функции. Например:

void swap(int &x, int &y)
{
    int z = x;
    x = y;
    y = z;
}
int a = 2; b = 3;
swap(a, b); // a IS THE SAME AS x inside the swap function

Итак, возвращение эталонного значения означает, что значение может быть изменено, например:

class Foo
{
public:
    ...
    int &val() { return m_val; }
private:
    int m_val;
};

Foo f;
f.val() = 4; // Will change m_val.

Подробнее о ссылках: C ++ Faq Lite - Семантика ссылок и значений

Теперь, отвечая на ваши вопросы

const int exampleOne();

Означает, что возвращаемый объект не может быть изменен через переменную. Это более полезно при возврате объектов.

int& exampleTwo();

Означает, что возвращаемый объект такой же, как и внутри функции, и любые изменения, сделанные в этом объекте, будут отражаться внутри функции .

const int& exampleThree();

Означает возвращаемый объект такой же, как и внутри функции, и не может быть изменен с помощью этой переменной.

0
ответ дан 1 December 2019 в 19:23
поделиться

Никогда не думал, что мы можем вернуть константное значение по ссылке, и я не вижу значения при этом .. Но это имеет смысл, если вы попытаетесь передать значение в функцию, подобную этой

void func(const int& a);

. Это имеет преимущество, заключающееся в том, что компилятору запрещается делать копию переменной a в памяти (что делается, когда вы передаете аргумент по значению). а не по ссылке). Const здесь для того, чтобы избежать изменения переменной a.

0
ответ дан 1 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: