검색결과 리스트
글
C++ 11 Non-static data member initializers
웹 컴파일러 링크 : http://melpon.org/wandbox/
C++ 98 에서는 오직 정수 타입의 정적 상수 멤버들 만이 클래스 내부에서 초기화 될 수 있었고 초기화 값은 반드시 상수 식이어야했다.
이러한 제약 조건은 컴파일 타임에 초기화가 될 수 있게 보장을 했다. 예를 들어
int var = 7;
class CTest {
static const int m1 = 7; // 가능
const int m2 = 7; // 오류 : static 아님
static int m3 = 7; // 오류 : const 아님
static const int m4 = var; // 오류 : 초기화값이 상수 식이 아니다
// const int var = 7 는 가능
static const string m5 = "odd"; // 오류 : 정수 타입이 아닙니다
// ...
};
C++ 11 에서는 기본적으로 비 정적 데이터 멤버들도 클래스 안에 선언된 부분에서 바로 초기화가 가능하다.
class CTest
{
private :
int m_iMember = 0;
};
는 아래 코드와 동일하다.
class CTest
{
public :
CTest() : m_iMember(0) {}
private :
int m_iMember = 0;
};
이는 타이핑을 줄여줄뿐만 아니라 여러개의 생성자를 가지고 있는 클래스들을 사용할 때 도움이 된다.
많은 경우 모든 생성자가 특정 멤버에 대해 공통적인 초기화 값을 가지는 경우가 있다.
class C {
public:
A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(int a val) : a(a val), b(5), hash_algorithm("MD5"), s("Constructor run") {}
A(D d) : a(7), b(Func(d)), hash_algorithm("MD5"), s("Constructor run") {}
private:
HashingFunction hash_algorithm; // 모든 A 인스턴스들에 대해 암호화 된 해시가 적용된다
std::string s; // 객체 생존사이클에 대한 상태를 나타내기 위한 문자열
int a, b;
};
hash_algorithm 과 s 모두 디폴드 값이 있다는 사실을 위의 혼잡한 코드에서 쉽게 눈치채기는 어렵고 유지 보수시에 문제가 될 가능성이 있다.
대신 C++ 11 에서는 데이터 멤버들의 초기화를 다음과 같이 수행할 수 있다.
class A {
public:
A(): a(7), b(5) {}
A(int a val) : a(a val), b(5) {}
A(D d) : a(7), b(Func(d)) {}
private:
HashingFunction hash_algorithm{"MD5"}; // 모든 A 인스턴스들에 대해 암호화 된 해시가 적용된다
std::string s{"Constructor run"}; // 객체 생존사이클에 대한 상태를 나타내기 위한 문자열
int a, b;
};
만약 멤버가 클래스 내부와 생성자 양쪽에서 초기화 된다면 생성자에 의한 초기화만 수행된다. (즉, 디폴트를 오버라이드한다.)
따라서 아래와 같이 더 간단한 표현이 가능하다.
class A {
public :
A() {}
A(int a_val) : a(a_val) {}
A(D d) : b(Func(d)) {}
private:
HashingFunction hash_algorithm{"MD5"}; // 모든 A 인스턴스들에 대해 암호화 된 해시가 적용된다
std::string s{"Constructor run"}; // 객체 생존사이클에 대한 상태를 나타내기 위한 문자열
int a = 7;
int b = 5;
};
참고 :
- [N2628 = 08 − 0138] Michael Spertus and Bill Seymour: Non-static data member initializers.
RECENT COMMENT