2

다음은 생성자를 테스트하기위한 스 니펫입니다. 그것은 내 생각에 "B b (B())"는 "B b = B()"와 같은 기능을하지만, 내 코드는 다른 행동을한다고합니다.익명 객체를 사용할 때 Default Constructor 또는 Copy Constructor가 호출되지 않습니다.

나는 컴파일러 최적화에 의한 복사 elision을 알고 있지만 기본 생성자는 적어도 "B b (B())"를 호출 할 때 호출되어야한다고 생각합니다. 누군가 내 오해가있는 부분을 지적 할 수 있습니까?

class B 
{ 
public: 
    B() { 
     ++i; 
     x = new int[100]; 
     cout << "default constructor!"<<" "<<i << endl; 
     cout << "x address:" << x << endl << "--------" << endl; 
    } 
    B(const B &b) //copy constructor 
    { 
     ++i; 
     cout << "Copy constructor & called " << i<< endl 
      << "--------" << endl; 
    } 
    B(B &&b)//move constructor 
    { 
     x = b.x;  
     ++i; 
     b.x = nullptr; 
     cout << "Copy constructor && called" << i << endl 
      <<"x address:"<< x << endl << "--------" << endl; 

    } 
    void print() 
    { 
     cout << "b address:" << x << endl << "--------" << endl; 
    } 
private: 
    static int i; 
    int *x; 
}; 
int B::i = 0; 


int main() 
{ 
    B b1; //default constructor 
    b1.print(); 
    B b2 = B(); //default constructor only 
    b2.print(); 
    B b3(B()); //????nothing called... why??? 
    B b4 = b2; //copy constructor 
    B b5 = move(b2); //move constructor 
    b2.print(); 

    return 0; 
} 
B b(B()) 함수 선언, 전혀, 다음 생성자가 호출되지 않을 것이다 변수 정의입니다

enter image description here

답변

4

참고.

Most vexing parse에 따르면 B b(B())B의 객체를 반환 입력 B 복귀 어떠한 파라미터를 고려하지 함수의 포인터를 단일 (이름) 매개 변수가 b라는 함수 함수 선언된다.

당신은 ((list initlization 이후 C++ 11))를 사용하여 중괄호를 해결할 수

B b1(B{}); 
B b2{ B() }; 
B b3{ B{} }; // preferable from C++11 
+0

멋진 캐치처럼! @ Shirley Feng, wiki 기사에 따르면, 내부 ctor 호출에 괄호를 추가하여 예상되는 동작을 얻을 수 있습니다. 예 :'B b3 ((B())); ' – souldzin

+0

공유 해 주셔서 감사합니다 !! 그것은 나를 구할 것입니다. XD –

+0

초기화에 하나의 컨벤션을 계속 사용하는 것이 낫지 않을까요? 즉'B b {B {}}; 대신 –