Что такое const & do? - PullRequest
       0

Что такое const & do?

0 голосов
/ 31 декабря 2011

Я не понимаю, что происходит.Я только изучаю C ++ и вижу нечто подобное:

double some_function(const Struct_Name& s) {
    ...
}

Почему const, если мы передаем по ссылке?

Ответы [ 7 ]

5 голосов
/ 31 декабря 2011

Вы передаете по константной ссылке, когда не хотите (или не можете) изменить передаваемый аргумент, и не хотите, чтобы производительность снизилась при копировании объекта.

4 голосов
/ 31 декабря 2011
Ссылка

A const предотвращает изменение объекта, как это делает const в любом другом месте, но также избегает потенциальных затрат на копирование.

3 голосов
/ 31 декабря 2011

Вы говорите компилятору, что никогда не будете менять s.

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

2 голосов
/ 31 декабря 2011

Используя const, мы можем сообщить как пользователю функции, так и компилятору, что объект, переданный в качестве аргумента s, не будет изменен внутри функции (что на самом деле было бы возможно, потому что мы передаем его по ссылке!).Затем компилятор может выдать нам ошибку, если мы изменим объект случайно, и он может выполнить некоторые оптимизации, которые он не мог бы сделать иначе.

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

2 голосов
/ 31 декабря 2011

Вызов по const-reference позволяет избежать копирования Struct_Name, обещая не изменять его.

Для этого есть и причина производительности, и причина семантики.

Если Struct_Name большой, его копирование обходится дорого как по времени, так и по памяти.

Если Struct_Name невозможно скопировать (или становится недействительным при копировании), вызов по значению невозможен или представляет нежелательную сложность. Например: std::unique_ptr и std::auto_ptr.

1 голос
/ 31 декабря 2011

Еще одна причина, о которой еще никто не упомянул - передача по ссылке const позволяет компилятору создавать и передавать временный объект, не генерируя предупреждение, если входное значение не является точным типом, объявленным в параметре, но Тип имеет конструктор, который поддерживает передаваемый тип.

Например:

void foo(const std::string &s)
{
    ...
}

foo("hello"); // OK

foo() ожидает std::string, но вместо этого получает const char*. Поскольку std::string имеет конструктор, который принимает const char*, компилятор генерирует код, который эффективно делает это:

std::string temp("hello");
foo(temp);

Компилятор знает, что параметр const, временное значение не будет изменено foo(), а временное будет отброшено после выхода foo(), поэтому он не жалуется на необходимость создания временного.

То же самое происходит, если параметр передается по значению (const или не- const, это не имеет значения) вместо ссылки:

void foo(const std::string s)
{
    ...
}

void bar(std::string s)
{
    ...
}

foo("hello"); // OK
bar("world"); // OK

Это фактически так же, как это:

{
std::string temp1("hello");
foo(temp1);
}

{
std::string temp2("world");
bar(temp2);
}

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

Если бы параметр был ссылкой не const, передача const char* выдаст предупреждение о временном объекте, который должен быть создан для удовлетворения привязки ссылки. Предупреждение состоит в том, что вы должны знать, что любые изменения, вносимые функцией во временную (поскольку она не const), будут потеряны при выходе из функции, что может повлиять или не повлиять на вызывающий код. Обычно это признак того, что временное не должно использоваться в этой ситуации:

void foo(std::string &s)
{
    ...
}

foo("hello"); // warning!
1 голос
/ 31 декабря 2011

const здесь обещает, что some_function не изменит параметр s,

double some_function(const Struct_Name& s) {
    ...
}

вы можете попытаться изменить его, но компилятор вернет ошибки.На самом деле constness требует от вас тщательного написания внутренних методов Struct_Name, т.е.Вы не сможете вызывать неконстантные функции some_function для объекта s.Вы можете попробовать, но вы получите ошибку.то есть:

struct Struct_Name {
  void myfun() const { } // can be called from some_function
  void myfun2() { } // will show error if called from some_function
};

Использование параметра const хорошо с точки зрения проектирования, если вы знаете, что какая-то функция не должна изменять ваш объект, тогда вы добавляете const.Это означает, что никакой другой программист не может вносить изменения в какой-то глубоко скрытый в коде иерархии классов, который изменит ваш объект.Это действительно облегчает отладку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...