Namespaces
Variants

Value-initialization

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

이는 빈 초기화자로 객체가 생성될 때 수행되는 초기화입니다.

목차

구문

T () (1)
new T () (2)
Class :: Class ( ... ) : member () { ... } (3)
T object {}; (4) (C++11 이후)
T {} (5) (C++11 이후)
new T {} (6) (C++11 이후)
Class :: Class ( ... ) : member {} { ... } (7) (C++11 이후)

설명

값 초기화는 다음과 같은 상황에서 수행됩니다:

1,5) 이름 없는 임시 객체가 빈 괄호 쌍으로 구성된 초기화자로 생성될 때 또는 중괄호 (C++11부터) ;
2,6) 동적 저장 기간을 가진 객체가 빈 괄호 쌍 또는 중괄호 (C++11부터) 로 구성된 초기화자를 사용한 new 표현식 에 의해 생성될 때;
3,7) 비정적 데이터 멤버나 기본 클래스가 빈 괄호 쌍을 사용하는 멤버 초기화 리스트 로 초기화될 때 또는 중괄호 (C++11부터) ;
4) 이름이 있는 객체(자동, 정적 또는 스레드-로컬)가 중괄호 쌍으로 구성된 초기화자와 함께 선언될 때.

모든 경우에, 빈 중괄호 쌍 {} 이 사용되고 T 가 aggregate type인 경우, aggregate initialization 이 value-initialization 대신 수행됩니다.

만약 T 가 기본 생성자를 가지지 않지만 std::initializer_list 를 취하는 생성자를 가진 클래스 타입인 경우, 목록 초기화 가 수행됩니다.

(C++11부터)

값 초기화의 효과는 다음과 같습니다:

  • 만약 T 가 (cv 한정자가 있을 수 있는) 클래스 타입인 경우:
  • 그렇지 않고 T 가 배열 타입인 경우, 배열의 각 요소가 값 초기화됩니다.
  • 그렇지 않은 경우, 객체는 제로 초기화됩니다.

참고 사항

구문 T object ( ) ; 는 객체를 초기화하지 않으며, 인수를 받지 않고 T 를 반환하는 함수를 선언합니다. C++11 이전에 명명된 변수를 값 초기화하는 방법은 T object = T ( ) ; 으로, 임시 객체를 값 초기화한 후 해당 객체를 복사 초기화하는 방식입니다: 대부분의 컴파일러는 이 경우 복사를 최적화하여 제거합니다 .

참조는 값 초기화될 수 없습니다.

함수 스타일 캐스트 에서 설명된 바와 같이, T ( ) (1) 구문은 T 가 배열 타입을 명시하는 경우 금지되지만, T { } (5) 구문은 허용됩니다.

모든 표준 컨테이너( std::vector , std::list 등)는 단일 size_type 인수로 생성될 때 또는 resize ( ) 호출로 크기가 증가할 때 해당 요소들을 값 초기화합니다. 단, 해당 할당자가 construct 의 동작을 사용자 정의하는 경우는 예외입니다.

예제

#include <cassert>
#include <iostream>
#include <string>
#include <vector>
struct T1
{
    int mem1;
    std::string mem2;
    virtual void foo() {} // T1이 aggregate가 아님을 보장
}; // 암시적 기본 생성자
struct T2
{
    int mem1;
    std::string mem2;
    T2(const T2&) {} // 사용자 제공 복사 생성자
};                   // 기본 생성자 없음
struct T3
{
    int mem1;
    std::string mem2;
    T3() {} // 사용자 제공 기본 생성자
};
std::string s{}; // 클래스 => 기본 초기화, 값은 ""
int main()
{
    int n{};                // 스칼라 => 제로 초기화, 값은 0
    assert(n == 0);
    double f = double();    // 스칼라 => 제로 초기화, 값은 0.0
    assert(f == 0.0);
    int* a = new int[10](); // 배열 => 각 요소의 값 초기화
    assert(a[9] == 0);      //          각 요소의 값은 0
    T1 t1{};                // 암시적 기본 생성자를 가진 클래스 =>
    assert(t1.mem1 == 0);   //     t1.mem1은 제로 초기화, 값은 0
    assert(t1.mem2 == "");  //     t1.mem2는 기본 초기화, 값은 ""
//  T2 t2{};                // 오류: 기본 생성자가 없는 클래스
    T3 t3{};                // 사용자 제공 기본 생성자를 가진 클래스 =>
    std::cout << t3.mem1;   //     t3.mem1은 기본 초기화되어 불확정 값
    assert(t3.mem2 == "");  //     t3.mem2는 기본 초기화, 값은 ""
    std::vector<int> v(3);  // 각 요소의 값 초기화
    assert(v[2] == 0);      // 각 요소의 값은 0
    std::cout << '\n';
    delete[] a;
}

가능한 출력:

42

결함 보고서

다음 동작 변경 결함 보고서는 이전에 게시된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 178 C++98 value-initialization이 없었음; 빈 초기화자는 default-
initialization을 수행했음 (비록 new T ( ) 는 zero-initialization도 수행했지만)
빈 초기화자는
value-initialization을 수행함
CWG 543 C++98 사용자 제공 생성자가 없는 클래스 객체에 대한 value-
initialization은 각 하위 객체를 value-initialization하는 것과
동등했음 (이는 사용자 제공 default constructor가 있는
멤버를 zero-initialize하지 않을 수 있음)
전체 객체를
zero-initialize한 후,
default constructor를
호출함
CWG 1301 C++11 삭제된 default constructor를 가진 union의 value-
initialization이 zero-initialization으로 이어짐
해당 union은
default-initialized됨
CWG 1368 C++98 어떤 사용자 제공 생성자라도 zero-initialization이
생략되도록 했음
사용자 제공 default constructor만이
zero-initialization을 생략함
CWG 1502 C++11 사용자 제공 default constructor가 없는 union을 value-
initializing할 때 default member initializer가 있음에도
객체만 zero-initialized됨
zero-initialization 후
default-initialization을
수행함
CWG 1507 C++98 사용자 제공 생성자가 없는 클래스 객체에 대한 value-
initialization은 default constructor가 trivial할 때
후자의 유효성을 검사하지 않았음
trivial default constructor의
유효성이 검사됨
CWG 2820 C++98 zero-initialization 이후의 default-initialization에
non-trivial constructor가 필요했음
필요하지 않음
CWG 2859 C++98 클래스 객체에 대한 value-initialization은 default-
initialization이 실제로 사용자 제공 constructor를
선택하지 않는 경우에도 zero-initialization을 수반할 수 있었음
이 경우
zero-initialization이
발생하지 않음

참고 항목