2013-02-12 3 views
2

안녕하세요.이 질문은 정말 기본적인 것이지만 혼란 스럽습니다. 객체를 생성했다고 가정 해 봅시다.복사 구성 객체에 대한 C++ 참조

MyObject a.

은 복사 생성자와 함께 제공, 그래서 내가이 작업을 수행 할 수 있습니다 알고

MyObject b(a); 을하지만이 작업을 수행 할 수 있습니까?

MyObject& b(a);

그리고 나는이 할 경우 :

MyObject b = a;b에 무엇을? 이 질문이 게시물을 귀찮게하는 것이 너무 근본적인 것이라면 사과하십시오.

답변

7

Doing MyObject& b(a)은 복사 생성자와 관련이 없습니다. 객체 a에 대한 참조 인 b을 만듭니다. 아무것도 복사되지 않습니다. ba 개체의 별칭으로 생각하십시오. ba을 사용하면 동일한 객체를 참조 할 수 있습니다.

MyObject b = a;은 복사 생성자를 사용합니다 (MyObject b(a);처럼).


는 초기화의 두 가지 형태가 있습니다 T x = a;복사 초기화로 알려져있다; T x(a)T x{a}직접 초기화으로 알려져 있습니다.

T이 참조 유형 인 경우 어떤 유형의 초기화가 사용되는지는 중요하지 않습니다. 둘 다 같은 효과가 있습니다. 이 복사본 초기화 경우 초기화가 a 유도되면서, 직접 초기화 (MyClass b(a);) 경우 또는

  1. :

    T

    우리는 두 가지 가능성을 가지고, 클래스 타입 T (MyClass b = a;)과 같은 유형 또는 동일한 유형 : T의 해당 생성자가 개체를 구성하기 위해 선택됩니다.

    두 가지 예제는이 클래스 유형 초기화 프로그램 범주에 속합니다.

  2. 초기화가 복사 초기화의 다른 형식이면 모든 사용자 정의 변환 시퀀스가 ​​고려되어 직접 초기화됩니다. 사용자 정의 변환 시퀀스는 기본적으로 단일 변환 생성자가있는 표준 변환의 모든 시퀀스입니다. cFoo 클래스 타입이었고 Foo에서 변환 생성자 MyClass에 있었다면

    , 다음 MyClass b = c;MyClass b(MyClass(c));에 해당 될 것이다.

기본적으로 소스 유형과 대상 유형이 같으면 두 형식의 초기화가 동일합니다. 변환이 필요한 경우 그렇지 않습니다. 이를 보여주는 간단한 예입니다

#include <iostream> 

struct Bar { }; 

struct Foo 
{ 
    Foo(const Foo& f) { std::cout << "Copy" << std::endl; } 
    Foo(const Bar& b) { std::cout << "Convert" << std::endl; } 
}; 

int main(int argc, const char* argv[]) 
{ 
    Bar b; 
    Foo f1(b); 
    std::cout << "----" << std::endl; 
    Foo f2 = b; 
    return 0; 
} 

(비활성화 복사 생략)와 함께이 프로그램의 출력은 다음과 같습니다

물론
Convert 
---- 
Convert 
Copy 

, 너무 initialisations 다른 종류의 많은 (목록 초기화가 , 문자 배열, 집계 등).

참조가 u는 참조에 액세스 할 때마다, 해당 스토리지를 액세스하는, 누군가 다른 사람의 스토리지에 연결되어 :

+0

맑은 설명. 감사! – user1861088

+0

'MyObject & b = a'는'MyObject & b (a)'와'MyObject b (a)'와'MyOjbect b = a '를 절대적으로 동일하게합니까? – user1861088

+0

@ user1861088 복사 초기화 대 직접 초기화를 검색하지 않습니다. –

0

여기 내이다. 참 조가 별명 일 뿐이므로 참조를 널에 지정할 수 없습니다. 참조는 생성 될 때 초기화되어야합니다. (포인터 언제든 초기화 될 수있다.)

그렇게하면

MyObject& b(a); 

컴파일러 저장소 (B)의 일부를 할당하고, 참조를 묶어 말하면. 당신이

MyObject b = a; 

을 말할 때

당신은 복사 생성자에의 참조를 전달하고 그것에서 새로운 B를 작성합니다. 그것을 위해 쓰여진 복사 생성자가있는 경우에만 깊은 복사가 있음에 유의하십시오. 그렇지 않은 경우는, 디폴트의 복사 생성자을 호출 해, 결과적으로 얕은 카피가 작성됩니다.

하고 당신이 그것을 호출 연산자 = (const를 객체 &), 따라서 A.operator = (B) : 객체로 변환

a = b; // after creating these objects 

말할 때 (생성자를 복사하지, 간단한 복사를 호출!)

+0

'MyObject & b (a)'라고 말할 때, 컴파일러는 저장소 조각 'a'를 할당하지 않고 그 저장소에 참조를 연결합니다. 'b'라는 참조를 할당하고'a'에 묶습니다. 복사 생성자가 전체 복사본을 생성한다고 말하는 것은 정확하지 않습니다 **. 그럴 수도 있지만 필수는 아닙니다. –

+0

@Nik : 내 대답을 편집했습니다. 깊은 사본을 잘 잡으려고, 나는 그가 유효한 복사 생성자를 가지고 있다고 가정하고 있었다. – DotNetUser

관련 문제