Использование const для параметров функции - PullRequest
347 голосов
/ 23 сентября 2008

Как далеко вы идете с const? Вы просто делаете функции const, когда это необходимо, или вы используете всю свинью и используете ее везде? Например, представьте себе простой мутатор, который принимает один логический параметр:

void SetValue(const bool b) { my_val_ = b; }

Это const действительно полезно? Лично я предпочитаю использовать его широко, включая параметры, но в этом случае мне интересно, стоит ли это делать?

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

.h file

void func(int n, long l);

.cpp file

void func(const int n, const long l)

Есть ли причина для этого? Это кажется мне немного необычным.

Ответы [ 30 ]

1 голос
/ 26 июля 2017

Подведем итог:

  • "Обычно const передача по значению не используется и в лучшем случае вводит в заблуждение." От GOTW006
  • Но вы можете добавить их в .cpp так же, как и с переменными.
  • Обратите внимание, что стандартная библиотека не использует const. Например. std::vector::at(size_type pos). То, что достаточно для стандартной библиотеки, хорошо для меня.
1 голос
/ 23 сентября 2008

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

Я не знал о разнице в объявлении файла .h / .cpp, но в этом есть какой-то смысл. На уровне машинного кода ничто не является «const», поэтому, если вы объявляете функцию (в .h) как неконстантную, код такой же, как если бы вы объявляли ее как const (без оптимизации). Тем не менее, это поможет вам подключить компилятор, чтобы вы не меняли значение переменной внутри реализации функции (.ccp). Это может пригодиться в том случае, если вы наследуете интерфейс, который допускает изменения, но вам не нужно менять параметр для достижения требуемой функциональности.

0 голосов
/ 28 мая 2017

Будучи программистом VB.NET, которому необходимо использовать программу на C ++ с более чем 50 открытыми функциями и файлом .h, который время от времени использует квалификатор const, трудно понять, когда обращаться к переменной с помощью ByRef или ByVal.

Конечно, программа сообщает вам, генерируя ошибку исключения в строке, где вы допустили ошибку, но затем вам нужно угадать, какой из 2-10 параметров является неправильным.

Итак, теперь у меня есть неприятная задача - убедить разработчика в том, что он действительно должен определить свои переменные (в файле .h) таким образом, чтобы позволить автоматизированный метод простого создания всех определений функций VB.NET. Затем они самодовольно скажут: «Прочитайте ... документацию».

Я написал сценарий awk, который анализирует файл .h и создает все команды объявления функций, но без указания того, какие переменные являются R / O против R / W, он выполняет только половину работы.

EDIT:

При поддержке другого пользователя я добавляю следующее:

Вот пример (IMO) плохо сформированной записи .h;

typedef int (EE_STDCALL *Do_SomethingPtr)( int smfID, const char* cursor_name, const char* sql );

Результирующий VB из моего скрипта;

    Declare Function Do_Something Lib "SomeOther.DLL" (ByRef smfID As Integer, ByVal cursor_name As String, ByVal sql As String) As Integer

Обратите внимание на пропущенное «const» в первом параметре. Без этого программа (или другой разработчик) не имеет идеи, 1-й параметр должен быть передан «ByVal». При добавлении «const» файл .h самодокументируется, поэтому разработчики, использующие другие языки, могут легко написать рабочий код.

0 голосов
/ 08 апреля 2015

Я знаю, что этот вопрос "немного" устарел, но когда я наткнулся на него, кто-то еще может сделать это в будущем ... ... все же я сомневаюсь, что бедняга перечислит здесь, чтобы прочитать мой комментарий:)

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

#include <iostream>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class SharedBuffer {
private:

  int fakeData;

  int const & Get_(int i) const
  {

    std::cout << "Accessing buffer element" << std::endl;
    return fakeData;

  }

public:

  int & operator[](int i)
  {

    Unique();
    return const_cast<int &>(Get_(i));

  }

  int const & operator[](int i) const
  {

    return Get_(i);

  }

  void Unique()
  {

    std::cout << "Making buffer unique (expensive operation)" << std::endl;

  }

};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NonConstF(SharedBuffer x)
{

  x[0] = 1;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ConstF(const SharedBuffer x)
{

  int q = x[0];

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main()
{

  SharedBuffer x;

  NonConstF(x);

  std::cout << std::endl;

  ConstF(x);

  return 0;

}

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

0 голосов
/ 23 сентября 2008

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

Используйте const, когда вы хотите, чтобы что-то не изменилось - это дополнительная подсказка, которая описывает, что делает ваша функция и чего ожидать. Я видел много C API, которые могли бы работать с некоторыми из них, особенно те, которые принимают c-строки!

Я бы более склонен опустить ключевое слово const в файле cpp, чем заголовок, но, поскольку я склонен их вырезать и вставлять, они будут храниться в обоих местах. Я понятия не имею, почему компилятор позволяет это, я думаю, это вещь компилятора. Лучше всего указывать ключевое слово const в обоих файлах.

0 голосов
/ 23 сентября 2008

Все константы в ваших примерах не имеют смысла. C ++ по умолчанию передается по значению, поэтому функция получает копии этих целых и логических значений. Даже если функция изменяет их, копия вызывающего не затрагивается.

Так что я бы избегал лишних констант, потому что

  • Они избыточны
  • Они загромождают текст
  • Они мешают мне изменение переданного значения в случаи, когда это может быть полезно или эффективно.
0 голосов
/ 23 сентября 2008

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

Причина использования «const» заключается в том, что вы передаете что-то большее (например, структуру с большим количеством элементов) по ссылке, и в этом случае это гарантирует, что функция не сможет ее изменить; вернее, компилятор будет жаловаться, если вы попытаетесь изменить его обычным способом. Это предотвращает его случайное изменение.

0 голосов
/ 23 сентября 2008

Параметр Const полезен только в том случае, если параметр передается по ссылке, то есть по ссылке или по указателю. Когда компилятор видит параметр const, он проверяет, что переменная, используемая в параметре, не изменяется в теле функции. Почему кто-то хочет сделать параметр по значению как константу? : -)

0 голосов
/ 23 сентября 2008

Я бы не стал использовать const для таких параметров - все уже знают, что логическое значение (в отличие от логического &) является постоянным, поэтому добавление его заставит людей думать: «Подожди, что?» или даже что вы передаете параметр по ссылке.

0 голосов
/ 23 сентября 2008

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

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