2009-12-26 5 views
5

저는 C++을 배우고 있습니다. C++ Primer plus. 그러나 나는 방금 cplusplus 웹 사이트를 체크 아웃하고 파일 핸들링을 약간 건너 뛰었습니다.'대괄호 초기화'. (C++)

나는 자바, PHP, 비주얼 베이직에서 나오는 파일 핸들링의 기초를 거의 알고있다. 그러나 나는 꽤 이상한 선을 가로 질러왔다.

ostream os(&fb); 

fb는 filebuf를 나타냅니다. 난 그냥이의 구문을 얻을하지 않습니다,하지만 난 그게 같은 있다는 알아낼 수 :

ostream os = &fb; 

하지만 난 정말 변수를 초기화하는이 방법에 대해 읽어 본 적이.

그래서 궁금합니다. 나는 단지 무의미한가하고 전체 유용한 기능을 놓치고 있습니까? 단지 오래된 것을 초기화하는 방법입니까? 뭔가 다른가요?

미리 감사드립니다.

답변

5

아마 당신은 복사 생성자가 호출 될 때 볼 thisthis

+0

위대한 참조 및 빠른 답변을 주셔서 감사합니다. –

+5

여기에 답변을 제공해야합니다. 다른 사람이이 질문에 답해야 할 필요가있을 때 링크가 작동하지 않을 수 있습니다. 이봐, 담당자를 원한다면 실제 답변을 게시해야합니다. 그것은 일반적으로 예의입니다. – jalf

+0

두번째 링크에서 가볍게 바꾸어 말하면 :'ostream os = &fb;'는 복사 초기화이고'os'는 항상'ostream'의 복사기를 사용하여 초기화됩니다. ("="은 C의 문법 유지이다. operator =는 절대 호출되지 않는다.) 컴파일러는 이런 상황에서 복사 생성을 최적화하는 것이 실제로 가능하다. 최적화를 수행하는 경우에도 복사 제어기에 계속 액세스 할 수 있어야합니다. ** 지침 : ** ostream os (& fb) 형식의 양식을 사용하십시오. 'ostream os = & fb'가 작동 할 때마다 항상 작동하며, 다른 장점 (예 : 여러 매개 변수를 사용할 수 있음)이 있습니다. –

5

작은 프로그램을 읽어야하고 오버로드 된 할당 연산자 함수가 호출 될 때 :

#include <iostream> 

using namespace std; 

class test 
{ 
    public: 
     // default constructor. 
     test() 
     { 
      cout<<"Default Ctor called"<<endl; 
     } 

     // copy constructor. 
     test(const test& other) 
     { 
      cout<<"Copy Ctor called"<<endl; 
     } 

     // overloaded assignment operator function. 
     test& operator=(const test& other) 
     { 
      cout<<"Overload operator function called"<<endl; 
      return *this; 
     } 
}; 

int main(void) 
{ 
    test obj1; // default constructor called. 

    test obj2 = obj1; // copy constructor called. 

    test obj3(obj2); // again copy constructor called. 

    obj1 = obj2; // overloaded assignment operator function. 

    return 0; 
} 

출력 :

Default Ctor called 
Copy Ctor called 
Copy Ctor called 
Overload operator function called 

따라서 귀하의 경우 ostream의 복사 생성자가 두 경우 모두 호출됩니다.

+0

나는 꽤 정확했다. D. 명확한 설명 주셔서 감사합니다. 즐거운 휴일! –

6

두 형식 모두 초기화을 수행합니다. 첫 번째 구문 (() 포함)을 직접 초기화 구문이라고합니다. 두 번째 구문 (=)을 복사 초기화 구문이라고합니다. 그들은 대부분의 실제 사례에서 똑같이 행동 할 것이지만 실제로는이 둘 사이에 차이가 있습니다.

왼쪽 (LHS)과 오른쪽 (RHS)의 유형이 동일 할 때 (const/volatile 한정자는 무시함) 두 경우 모두 실제로 동일합니다. 언어 표준은 명시 적으로이 경우 = 양식이 () 양식과 동일하다고 명시합니다.

그러나 유형이 다른 경우 (LHS 유형이 클래스 유형 인 경우)이 두 양식은 일반적으로 다르게 작동합니다. (모든 가능한 수단에 의해 : 표준 변환, 변환 연산자 변환 생성자) LHS 형의 임시 객체에 RHS 값 변환 :

  • 카피 초기화 형태는 다음과 같이 작동한다. 그런 다음 LHS 클래스의 복사 생성자를 사용하여 임시 객체를 LHS 객체에 복사합니다.

  • 직접 초기화 형식은 다음과 같이 작동합니다. LHS의 모든 생성자를 고려하고 과부하 해결을 사용하여 가장 적합한 구성을 선택합니다.

즉시 복사 초기화 구문은 무조건 복사 생성자를 사용하는 것을 알 수 있습니다 (복사 멀리 최적화 할 수 있습니다 중간 임시을하지만 개념적으로 그들은 거기에 있습니다).LHS 클래스에 접근 가능한 복사 생성자가 없다면 무조건 직접 초기화가 작동하는 반면 복사 초기화는 무조건 부적절하게된다.

또한 특정 생성자에 적용되는 키워드 explicit은 어떤 유형의 조합에 사용할 수있는 초기화 형식에 영향을줍니다.

+1

그냥 * 정확한 * 단어를 선택하려고합니다. (대답은 실제 표준의 답처럼 들릴 것 같기 때문에) : 복사 생성자가 명시 적이면 LHR과 RHS가 동일한 경우 '='구문이 실패합니다 '()'형식은 실패하지 않습니다. –

0

내 이해에 따라, & var은 var 변수의 별칭이며 어떤 변수를 사용하든 상관 없습니다.

-------- 추가 -----------------

아래의 코드는 모두가 그이 그 명확한 스트로브 스트 룹 book.From에서 가져

동일한 변수에 대한 별명. 또한 아래와 같이 말합니다.

"인수 전달의 의미는 초기화의 의미로 정의되므로 호출 될 때 increment의 인수 aa는 x의 다른 이름이됩니다." 그래서 & x를 x의 별명으로 간주했습니다. 함수 호출 초기화

void increment(int& aa) { aa++; }

void f() { int x = 1; increment(x); }

+0

아니요, '& var'는'var'의 주소입니다. 그들에는 다른 유형이있다; var가 T 유형이면 & var는 T * 유형입니다. –

+0

내 대답을 편집했습니다. 그것을 확인하십시오. – Boolean

1

한 가지 중요한 이점은 여러 인수를 생성자와 함께 작동한다는 것입니다. 예를 들어, fstream 생성자는 두 개의 매개 변수를 수행 할 수 있습니다 C++0x uniform initialization까지

std::fstream file("filename", ios_base::out); 

널리 사용할 수 있으며, 함수 호출 초기화는 여러 인수 생성자를 처리 할 수있는 유일한 방법입니다.