2010-12-08 5 views
9

나는 스마트 포인터를 이해하고 광산을 만들기 위해 놀고 있지만, 완전히 이해하지 못하는 상황을 경험하게된다. 여기 코드는 다음과 같습니다왜 할당 연산자 호출 생성자가 있습니까?

#include <iostream> 
template <class T> 
class Holder 
{ 
private: 
     T * obj; 
public: 
     Holder(T * tt) : obj(tt) 
     { 
       std::cout << "ctor : " << tt->dummy << std::endl; 
     } 
     T * operator ->() 
     { 
       return obj; 
     } 
     operator bool() 
     { 
       return obj; 
     } 
     T * const get() const 
     { 
       return obj; 
     } 
     void reset() {swap(0);} 
     void swap(T * other) 
     { 
       obj = other; 
     } 
     Holder & operator = (const Holder& holder) 
     { 
       obj = holder.get(); 
       return *this; 
     } 
     Holder(const Holder & holder) : obj(holder.get()) {} 
}; 

class A 
{ 
public: 
     int dummy; 
     A(int a) : dummy(a) {} 
}; 

int main() 
{ 
     A * a = new A(1); 
     Holder<A> holder(a); 
     A * b = new A(2); 
     holder = b; 

     std::cout << holder->dummy << std::endl; 

     return 0; 
} 

코드는 컴파일하고 holder = b;의 라인에 Holder 클래스의 생성자가 호출된다. 나는 컴파일러가 오류를 줄 것이라고 생각했다. assingment 연산자는 아니지만 constructor을 호출하는 이유는 무엇입니까?

+0

라고 A *의 오른쪽 걸리는 할당 연산자의 버전이 표시되지 않는 이유는 무엇입니까? – suszterpatt

+0

@suszterpatt : 홀더 (T * tt) –

답변

13

holder = bb에서 Holder으로 할당하려고 시도합니다. bA*이고 holderHolder<A>입니다.

Holder 템플릿은 같은 Holder 유형의 다른 인스턴스에서 할당을 정의, 그래서 컴파일러는 Holder<A>-A*에서 변환을 찾습니다. 생성자를 찾아서 사용합니다.

암시 적 변환에 정확히 하나의 인수를 사용할 수있는 생성자 explicit 키워드로 태그를 지정하지 않는 한 사용할 수 있습니다.

+0

+1은 "명시 적"입니다. 감사. –

0

T *를 취하는 생성자가 있습니다. 당신의 assigment에는 rhs 포인터가 있습니다. 그래서 포인터로 temp-obj를 인수로 구성하고 이것을 holder에 할당합니다.

4

생성자와 할당 연산자가 모두 호출됩니다. operator =에 무엇인가를 인쇄하여이를 확인할 수 있습니다.

operator =const Holder &이 되도 록 정의 되었기 때문에 이런 현상이 발생하지만 bA *입니다. 먼저 Holder(T *) 생성자가 임시 객체를 만들기 위해 호출되면이 객체는 holder에서 operator =으로 할당됩니다.

operator =(const T *)을 정의하면 대입 연산자 만 호출됩니다.

1

나는`Holder`는 두 개의 생성자를 가지고있는 하나를

A*  a  = new A(1); 
    Holder<A> holder(a); 
    A*  b   = new A(2); 

    // assigning object of type A* to Holder<A> 
    holder = b; 

    // No appropriate assignment operator provide. 
    // But a constructor is available to convert RHS parameter to correct type. 
    // So compiler generates the following code: 

    holder = Holder<A>(b); 

    // There is an appropriate assignment operator for this. 
    // So it compiles. 
관련 문제