2009-08-13 7 views

답변

79

이는 초기화 목록이며, 생성자의 구현의 일부 : - 귀하의 예에서, 오히려이 같은 (이 모든 경우에 해당의 의미하지 않는다 이런 일)입니다.

생성자의 서명은 다음과 같습니다

MyClass(); 

이 생성자는 매개 변수없이 호출 할 수 있다는 것을 의미한다. 이렇게하면 기본 생성자이됩니다. 즉, MyClass someObject;을 쓸 때 기본적으로 호출되는 것입니다.

부분 : m_classID(-1), m_userdata(0)초기화 목록이라고합니다. 이것은 정의되지 않은 것으로 남겨 두지 않고 원하는 값으로 개체의 일부 필드 (원하는 경우 모두 가능)를 초기화하는 방법입니다.

초기화 목록을 실행 한 후 생성자 본문 (예제에서 비어있게 됨)이 실행됩니다. 그 안에는 더 많은 할당을 할 수 있지만 일단 입력하면 모든 필드가 이미 초기화되었습니다. 즉 임의의 값, 지정되지 않은 값 또는 초기화 목록에서 선택한 값으로 초기화됩니다. 즉, 생성자 본문에서 수행하는 할당은 초기화가 아니라 값의 변경입니다.

2

이니셜 라이저 목록의 시작 부분은 개체의 멤버 변수를 초기화하기위한 것입니다.

는에 관해서는 : 인수를 할 수있는 생성자를 선언 MyClass(m_classID = -1, m_userdata = 0);

(그래서 m_classID 3 인, 그리고 m_userdata 4 인을 초래할 것 MyClass 사용 MyClass m = MyClass(3, 4), 만들 수 있습니다). MyClass 생성자에 인수를 전달하지 않으면 이니셜 라이저 목록이있는 버전에 해당하는 객체가 만들어집니다.

0

이 경우 예 : ist는 기본 유형에만 관련되어 있기 때문에 동일합니다.

멤버가 클래스 (구조체) 인 경우 초기화 목록을 선호해야합니다. 그렇지 않으면 개체가 기본적으로 생성 된 다음 할당됩니다.

1

그것은 initialization list입니다.


class MyClass { 

public: 

    MyClass(){ 
     m_classID = -1; 
     m_userdata = 0; 
    } 

    int m_classID; 
    void *m_userdata; 

};
2

이니셜 라이저 목록의 시작을 알립니다.

또한 MyClass (m_classId = -1, m_userData = 0)와 동일하지 않습니다. 이것은 기본값을 갖는 2 개의 매개 변수로 생성자를 정의하려고 시도하고 있습니다. 그러나 값에는 유형이 없으므로 컴파일 할 필요가 없습니다.

1

이것은 구성원 초기화 목록이라고합니다. 이 클래스는 수퍼 클래스 생성자를 호출하고 생성 된 멤버 변수에 초기 값을 제공하는 데 사용됩니다.

이 경우 m_classID을 -1로, m_userData을 NULL로 초기화합니다.

생성자 본문에 할당하는 것과 완전히 같지 않습니다. 왜냐하면 후자는 먼저 멤버 변수를 만든 다음 할당자를 할당하기 때문입니다. 초기화를 수행하면 생성시 초기 값이 제공되므로 복잡한 객체의 경우보다 효율적으로 처리 할 수 ​​있습니다.

+1

그것은을 사용하는 것이 필수는 때때로이다 멤버 초기화 목록 참조 변수 인 멤버 변수가있는 경우 멤버 초기화 목록을 사용하여 설정해야합니다. – Skurmedel

1

정확하게 연산자가 아닙니다. 그것은 생성자에 대한 구문의 일부입니다.

다음과 같은 내용은 멤버 변수와 초기 값 목록입니다.

상수 멤버는이 방법으로 초기화해야합니다. 비상 수식은 단일 표현식으로 수행 할 수있는 한 여기서도 초기화 할 수 있습니다. 멤버를 초기화하는 데 필요한 코드보다 더 많은 코드가 필요하다면 {} 사이에 실제 코드를 넣어야합니다.

많은 사람들이 거의 모든 생성자 코드를 initilizer 목록에 넣는 것을 좋아합니다. 필자는 초기화 화면의 여러 화면으로 정기적으로 클래스를 작성한 한 동료가 있으며 생성자 코드에 "{}"을 넣습니다.

1

개체를 생성하는 동안 멤버 변수를 설정하는 초기화 프로그램 목록의 시작입니다. 귀하의 예를 "MyClass (m_classID = -1, m_userdata = 0);"

MyClass(int classId = -1, void* userData = 0) : m_classID(classId), m_userdata(userData) {} 

initialiser 목록을보다 더 간주됩니다 올바른 생성자를 정의하지 않은 당신이 어떻게 든 매개 변수 목록에서 멤버 변수에 액세스 할 수없는 것처럼 당신이 뭔가를 할 수 ... 수 없습니다 :

MyClass(int classId = -1, void* userData = 0) { 
    m_classID = classId; 
    m_userdata = userData; 
} 

Google에 대한 자세한 정보

37

초기화 목록입니다.

생성자 본문에 들어가면 모든 필드가 이미 생성됩니다. 기본 생성자가 있으면 이미 호출 된 것입니다. 이제 생성자 본문에 값을 할당하면 복사 할당 연산자가 호출됩니다.이 연산자는 객체가있는 경우 리소스 (예 : 메모리)를 해제하고 다시 가져 오는 것을 의미 할 수 있습니다.

int와 같은 기본 유형의 경우에는 생성자 본문에 할당하는 것보다 이점이 없습니다. 생성자가있는 객체의 경우 두 객체 초기화 대신 하나의 객체 초기화를 수행하지 않으므로 성능 최적화가됩니다.

참조가 null 일 수 없기 때문에 필드 중 하나가 참조 인 경우 초기화 목록이 필요합니다. 객체 생성과 생성자 본문 사이의 짧은 시간이 아니기 때문에 초기화 목록이 필요합니다. 다음은 오류 C2758을 제기 : 'MyClass에 :: member_이': 생성자 기본/멤버 이니셜 라이저 목록에 초기화해야합니다

class MyClass { 
public : 
    MyClass(std::string& arg) { 
     member_ = arg; 
    } 
    std::string& member_; 
}; 

유일한 올바른 방법은 다음과 같습니다

class MyClass { 
public : 
    MyClass(std::string& arg) 
     : member_(arg) 
    { 
    } 
    std::string& member_; 
}; 
+2

참조 멤버가 있으면 생성자 이니셜 라이저 목록을 사용하여 생성자를 정의해야한다고 잘못 믿는 경우가 종종 있습니다.그러나 그것은 사실이 아닙니다. 간단한 'MyClass m = {arg};는 잘 작동합니다. –

+0

litb : 그렇다면 m = {arg}를 사용하는 것이 더 많거나 적습니다. 너 아냐? 내 눈에는 MyClass m (ref)을 수행 할 수 있다는 것이 아주 바람직합니다. – Skurmedel

+0

@Skurmedel, 동의합니다. 그렇다고해서 그것을하는 것이 유일한 방법은 아닙니다. –