Rule No. 1 of changing your code to optimize performance, is:
Don't do it, unless you are are sure you have a performance problem, and you are sure that the change you are making will actually make a difference.
Otherwise, you're just wasting your time, and quite possible compromising something else (e.g. design, code clarity) for no benefit.
So you're creating additional named objects, and additional temporary un-named objects. So what? C++ programs do this all the time. Modern computers are fast, and unless you're doing this a very large number of times, it won't make any noticeable difference to the performance of your program. There's absolutely no need to worry about it.
Now, if, when you run your program, you think there's an actual performance problem you need to worry about, the first thing you need to do is discover what's causing the problem. Use profiling software to benchmark your program, and discover which operations are taking the most time, and
then try and come up with solutions to make those operations faster.
Hypothetically, it turned out that you did need to avoid making these copies some techniques you could use are:
1) Pass in an object by reference, and have your function populate that object
2) Dynamically allocate the object in the function, and simply return a pointer
3) Be aware that copy elision is a thing:
https://en.cppreference.com/w/cpp/language/copy_elision
4) Use move semantics:
https://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html