Краткий ответ:
В1. Учитывая размер вашего класса MyAppCtx, да, если данные обрабатываются очень часто, произойдет значительное снижение производительности.
Q2: минимально, вы передаете указатель.
В3: Ни для больших объектов, подобных этому, не следует использовать эталонную семантику и обращаться к данным через средства доступа. Не беспокойтесь о накладных расходах на вызовы функций, при включенной оптимизации компилятор может встроить их, если они отвечают различным критериям (которые я оставляю на ваше усмотрение, чтобы выяснить).
Длинный ответ:
Предоставленные функции:
void FuncByValue(MyAppCtx ctx);
void FuncByRef1(MyAppCtx& ctx);
void FuncByRef2(MyAppCtx* ctx);
При передаче больших объектов, таких как MyApplicationCtx, рекомендуется использовать семантику ссылок (FuncByRef1 & FuncByRef2), передача по ссылке идентична по производительности передаче указателя, разница только в синтаксисе. Если вы передаете объект по значению, объект создается в функции копирования, так что аргумент, передаваемый в FuncByValue, отличается от параметра, который получает FuncByValue. Здесь вы должны быть осторожны с указателями (если они есть), содержащимися в объекте, который был передан по значению, потому что указатель также будет скопирован, поэтому очень возможно, что более одного объекта будут указывать на один элемент в памяти в определенный момент времени, что может привести к утечкам памяти, повреждению и т. д.
В целом, для таких объектов, как ваш MyAppCtx, я бы рекомендовал передавать по ссылке и использовать соответствующие методы доступа.
Обратите внимание, причина, по которой я различил аргумент и параметр выше, заключается в том, что между аргументом функции и параметром функции есть разница:
Дано (шаблон T используется просто для демонстрации того, что тип объекта здесь не имеет значения):
template<typename T>
void MyFunc(T myTobject);
При вызове MyFunc вы передаете аргумент, например:
int my_arg = 3;
MyFunc(my_arg);
И MyFunc получает параметр, например:
template<typename T>
void MyFunc(T myTobject)
{
T cloned_param = T(myTobject);
}
Другими словами, my_arg
- это аргумент, myTobject
- это параметр.
Еще одно замечание: в приведенных выше примерах в памяти по существу присутствуют три версии my_arg
: исходный аргумент, созданный при копировании параметр myTobject
, плюс cloned_param, который также был явно скопирован.