2

Ниже приведен фрагмент, предназначенный для тестирования конструкторов. Он был запущен в VS 2015.Конструктор ни по умолчанию, ни конструктор копирования не вызывается при использовании анонимного объекта

На мой взгляд, «B b (B())» имеет ту же функцию, что и «B b = B()», однако мой код, кажется, говорит, что они ведут себя по-другому.

Я знаю, что существует оптимизация при копировании, но я думаю, что конструктор по умолчанию должен вызываться по крайней мере, когда выполняется «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; 
} 

enter image description here

ответ

4

Обратите внимание, что B b(B()) является объявлением функции, а не определение переменной вообще, то ни один конструктор не будет называться.

Согласно 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 {}}; вместо –

 Смежные вопросы

  • Нет связанных вопросов^_^