Вызов метода, который возвращает структуру, будет вести себя так, как будто вызывающая сторона создает временную переменную типа структуры где-то, что не видно в любой другой области видимости, и дает вызываемой функции указатель на нее. Затем вызываемая функция поместит данные в запрошенное место, а после возврата вызывающая сторона сможет прочитать данные из своей новой переменной. Дана функция и код вызова:
StructType BuildStruct(void)
{
StructType it;
it.this=4;
it.that=23;
return it;
}
StructType myStruct;
myStruct = BuildStruct();
вполне вероятно, что будет хотя бы одна операция копирования, если не две; оператору return it;
может потребоваться скопировать из локальной переменной it
во временную структуру, а присвоение myStruct
может потребоваться для копирования из временного расположения в myStruct
. На самом деле ни одна ситуация не требует двух операций копирования; некоторые требуют один (который может быть выполнен вызывающим или вызываемым методом), а некоторые - нет, но необходимость копирования зависит от деталей как в вызывающем, так и в вызываемом методе.
Альтернативный дизайн будет:
void BuildStruct(StructType *it)
{
it->this=4;
it->that=23;
}
StructType myStruct;
BuildStruct(&myStruct);
Это, вероятно, приведет к коду, эквивалентному лучшему коду, на который можно было бы надеяться, используя возвращаемую переменную структурного типа, поскольку данные структуры будут помещены непосредственно в конечное место без необходимости какого-либо копирования структуры.