In C++, there are direct (direct) and copy (copy) initialization of objects:
Direct initialization:
MyClass obj(arg1, arg2); int x(5);
For classes, it calls the appropriate constructor directly.
Copy initialization:
MyClass obj = MyClass(arg1, arg2); int x = 5;
This creates a temporary object and then copies (or moves) it (uses the copy/move constructor).
Differences:
Example:
struct NonCopyable { NonCopyable(int) {} NonCopyable(const NonCopyable&) = delete; }; NonCopyable a(5); // OK: direct NonCopyable b = NonCopyable(5); // OK with optimization, error before C++17 without it NonCopyable c = 5; // Error: no copy constructor
"Can copy-initialization result in more constructor calls than direct-initialization if using C++11 with an optimizing compiler enabled?"
Answer: Theoretically — yes. Without copy elision, copy-initialization creates a temporary object and then calls the copy or move constructor. Direct-initialization always calls only the primary constructor. However, modern compilers with optimization enabled (C++17 and above) eliminate this difference due to guaranteed copy elision.
Story
In a financial project, copy-initialization with a temporary object was used, and the required type did not have a copy constructor. The application would not compile on older compilers (before C++17), although direct-init worked.
Story
In a data serialization utility, programmers thought that direct-init and copy-init were equivalent. As a result, unnecessary copies of large structures occurred, leading to performance issues.
Story
When initializing global arrays of user-defined objects, copy initialization was used. Errors appeared only on one platform where copy elision did not occur, resulting in implicit calls of unnecessary constructors due to ABI peculiarities.