C++ Copy Initialization | "Copy Initialization" Guide
이 글의 핵심
Copy initialization (T x = v): implicit conversions, explicit constructors, and how it differs from direct and list initialization.
What is Copy Initialization?
Copy initialization is a way to initialize variables using the = expr syntax. It is distinct from list initialization {} and is often optimized away through move semantics or RVO/NRVO. Understanding it alongside copy and move constructors helps clarify its behavior.
int x = 10; // Copy initialization
std::string s = "Hi"; // Copy initialization
int y(10); // Direct initialization
std::string s2("Hi"); // Direct initialization
Direct Initialization vs Copy Initialization
class Widget {
public:
explicit Widget(int x) {}
};
// ❌ Copy initialization: explicit constructor not allowed
// Widget w1 = 10;
// ✅ Direct initialization: explicit constructor allowed
Widget w2(10);
Widget w3{10};
Practical Examples
Example 1: Primitive Types
// Copy initialization
int x = 10;
double d = 3.14;
char c = 'A';
// Direct initialization
int x(10);
double d(3.14);
char c('A');
// Uniform initialization
int x{10};
double d{3.14};
char c{'A'};
Example 2: Classes
class String {
std::string data;
public:
String(const char* str) : data(str) {}
String(const String& other) : data(other.data) {
std::cout << "Copy constructor" << std::endl;
}
};
// Copy initialization
String s1 = "Hello"; // const char* -> String
// Direct initialization
String s2("Hello");
Example 3: Implicit Conversions
class Number {
int value;
public:
Number(int v) : value(v) {} // Allows implicit conversion
};
void func(Number n) {}
int main() {
func(42); // int -> Number (copy initialization)
Number n = 42; // Copy initialization
}
Example 4: Return Values
std::string getName() {
return "Alice"; // Copy initialization
}
int getValue() {
int x = 10;
return x; // Copy initialization
}
explicit and Initialization
class Widget {
public:
explicit Widget(int x) {}
};
// ❌ Copy initialization
// Widget w1 = 10;
// void func(Widget w) {}
// func(10);
// ✅ Direct initialization
Widget w2(10);
Widget w3{10};
Common Issues
Issue 1: Explicit Constructor
class Array {
public:
explicit Array(size_t size) {}
};
// ❌ Copy initialization
// Array arr = 10;
// ✅ Direct initialization
Array arr(10);
Array arr2{10};
Issue 2: Conversion Operators
class Fraction {
public:
Fraction(int n, int d) {}
operator double() const {
return /* ... */;
}
};
Fraction f(1, 2);
double d = f; // Copy initialization (conversion)
Issue 3: Initialization Lists
// Copy initialization
std::vector<int> v1 = {1, 2, 3};
// Direct initialization
std::vector<int> v2{1, 2, 3};
// Both produce the same result
Issue 4: auto Type Deduction
auto x = 10; // int
auto y = {10}; // initializer_list<int>
auto z{10}; // C++17: int, C++11/14: initializer_list<int>
Performance Considerations
// Copy initialization
std::string s1 = "Hello"; // Temporary object may be created
// Direct initialization
std::string s2("Hello"); // Direct construction
// Optimized with RVO
FAQ
Q1: What is copy initialization?
A: Uses =. Allows implicit conversions.
Q2: What is direct initialization?
A: Uses () or {}. Allows explicit constructors.
Q3: What’s the difference?
A: Whether explicit constructors can be invoked.
Q4: What about performance?
A: Optimized with RVO. No significant difference.
Q5: When should I use each?
A:
- Copy: For simple initializations.
- Direct: When explicit constructors are needed.
Q6: Where can I learn more about copy initialization?
A:
- “Effective C++”
- “C++ Primer”
- cppreference.com
Related Posts: List Initialization, Move Semantics, Copy and Move Constructors, RVO/NRVO.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ List Initialization | “리스트 초기화” 가이드
- C++ Move 시맨틱스 | “복사 vs 이동” 완벽 이해
- C++ 복사/이동 생성자 | “Rule of Five” 가이드
- C++ RVO/NRVO | “Return Value Optimization” 가이드
이 글에서 다루는 키워드 (관련 검색어)
C++, copy-initialization, direct-initialization, initialization, conversion 등으로 검색하시면 이 글이 도움이 됩니다.