C ++ Когда имеет смысл передавать параметр const struct по значению или по ссылке? - PullRequest
0 голосов
/ 08 сентября 2018

Я видел похожий вопрос к этому, но я хотел бы получить разъяснения ...

Предполагая базовый класс C ++:

class MyClass
{
public:
    struct SomeData
    {
        std::wstring name;
        std::vector<int> someValues;
    };

    void DoSomething(const SomeData data);
}

Я понимаю, что data будет передано как const в DoSomething, и это нормально, так как data не будет изменяться каким-либо образом функцией ... но я привык видеть & задается параметрами const, чтобы гарантировать, что они передаются по ссылке, например

void DoSomething(const SomeData& data);

Это кажется мне более эффективным. Если мы опускаем &, то не передается ли data по значению DoSomething? Я не уверен, почему было бы предпочтительнее передавать параметр const по значению, если вы можете передать по ссылке и избежать копирования?

Ответы [ 4 ]

0 голосов
/ 08 сентября 2018

Самая большая проблема с void DoSomething(const SomeData data) заключается в том, что он объединяет интерфейс и реализацию. С точки зрения звонящего, const ничего не меняет; функция все равно получает копию, а исходный объект не изменяется. То, что реализация делает или не делает со своей собственной функцией-внутренней копией, не должно беспокоить вызывающую сторону и, следовательно, не должно быть выражено в интерфейсе.

const делает реализацию более корректной, если копия не изменена, но утечка деталей реализации в интерфейс - высокая цена. Я рекомендую не использовать void DoSomething(const SomeData data).

Как всегда, прирост производительности или потери не следует переоценивать здесь. Это больше о семантике и соглашениях.

0 голосов
/ 08 сентября 2018

Это:

void DoSomething(const SomeData data);

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

Передача по ссылке (постоянная или нет) более эффективна, если копировать значение дорого, в том числе если оно превышает приблизительно два указателя на целевой платформе. Другими словами, если бы SomeData была структурой, содержащей два целых числа, вероятно, было бы более эффективно передать ее по значению. Но если он содержит std::map или более крупные данные, лучше передать его по ссылке.

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

0 голосов
/ 08 сентября 2018

Передача по значению / эталону и константность - это две разные концепции. Но используется вместе.

Передача по значению

 void DoSomething (SomeData data);

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

Передача по ссылке

void DoSomething (SomeData& data);

Всегда используйте передачу по ссылке, если знаете, что это может привести к снижению производительности при копировании структуры. Эта функция может (если она находится внутри класса) в некоторых случаях сохранять указатель на это и указывать на сторонний объект. Сохранение указателей на посторонние объекты означает, что вы должны знать о времени его жизни и о том, когда этот посторонний объект выходит за пределы. Что более важно, изменения в чужом объекте появляются в вашем указателе.

постоянная корректность

void DoSomething (const SomeData data);  // const for local copy
void DoSomething (const SomeData& data); //  const for callers object

Добавление const для передачи по значению или ссылке означает, что эта функция не меняет его. Но отсутствие или наличие & решает, к какому объекту вы пытаетесь добавить безопасность изменения. const - очень полезный инструмент в C ++ с точки зрения API документирования, обеспечивает безопасность времени компиляции, позволяет оптимизировать компиляцию.

Читать эту статью.

0 голосов
/ 08 сентября 2018

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

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

...