Неявное приведение в конструкторе класса

есть класс :

class myclass{
 int a;
 public:
 myclass(int p){a=p;};
};

int main()
{
 myclass mc=33; 
 myclass mc2=myclass(33);
}

Объясните, пожалуйста, что происходит в 1 варианте? Во втором , я понимаю, что создается класс myclass , вызывается конструктор для него , и этот класс экземпляр копируется в mc2.


Ответы (1 шт):

Автор решения: Andrej Levkovitch

Во-первых, ваши предположения о том, что происходит во втором варианте ошибочны. Коснтруктор копирования не будет вызван, вы можете это проверить сами если, например, удалите конструктор копирования (может не сработать, это зависит от компилятора) или добавите в него логи. Дело в том, что компилятор упрощает такие вызовы до простого вызова конструктора. Считайте что это оптимизация, которую нельзя отключить (насколько мне известно).

Во-вторых, первый вариант записи возможен из-за того, что ваш конструктор не помечен как explicit. В общем случае это все конструкторы с одним параметром следует помечать как explicit, чтобы избежать неявного преобразования (как в вашем примере).

Проверочный код:

#include <iostream>

class myclass {
  int a;

public:
  explicit myclass(int p) { a = p; };
  myclass(const myclass &) { std::cout << "copy" << std::endl; };
};

int main() {
  // XXX fail
  // myclass mc = 33;
  myclass mc2 = myclass(33);
}
→ Ссылка