A a_1 = A ("con 1");
Создает временный объект, вызывая конструктор, который принимает строку в качестве аргумента, поскольку переданный тип равен const char *
, компилятор должен сначала выполнить неявное преобразование в string
(), а затем использовать этот временный объект для копирования. построить новый a_1
объект.
Поскольку существует дополнительное неявное преобразование, компилятор не может оптимизировать это и должен сделать вызов конструктора копирования.
Основываясь на комментариях и дальнейших исследованиях, я сомневаюсь, что рассуждения (выше , выделенные курсивом ) верны.
@ Дэвид предлагает в своих комментариях:
копия не может быть исключена не из-за неявного преобразования, а потому, что преобразование является явным. То есть компилятор не может оптимизировать его, потому что код явно запрашивает создание временного объекта и конструкцию копии.
Однако ни @David, ни Me не могут подтвердить это с помощью стандартной цитаты.
A a_2 = "con 2";
создает объект a_2
, вызывая соответствующий конструктор, который принимает строку в качестве аргумента.
A a_3 = A (4);
Примечание в случае 1 также применяется здесь:
В идеале следует сконструировать временный объект, вызвав конструктор, который принимает целое число в качестве аргумента, а затем использовать этот временный объект для копирования, создать новый объект a_3
, как в случае 1, но компилятор может оптимизировать и напрямую сконструировать объект, вызвав конструктор, который принимает целое число как доступное
A a_4 = A ("a_4", 10);
Создает временный объект, вызывая конструктор, который принимает строку и целое число в качестве аргумента, а затем использует этот временный объект для копирования, создает новый объект a_4
.
A a_5 = A (11, "a_5");
Создает временный объект, вызывая конструктор, который принимает целое число и строку в качестве аргумента, а затем использует этот временный объект для копирования, создает новый объект a_5
.
Обратите внимание, что для вашего класса не определен конструктор Default.
Вы можете добиться того же более эффективным способом, избегая создания временного объекта и затем копируя конструирование объекта в вышеупомянутых случаях, не используя присваивание (=
).
A a_1("con 1");
A a_2("con 2");
A a_3(4);
A a_4("a_4", 10);
A a_5(11, "a_5");
Мой первоначальный ответ был при попытке объяснить поведение, но когда я скомпилировал это на gcc-4.3.4 на Ideone , я обнаружил, что gcc достаточно умен, чтобы оптимизировать копию вызов конструктора. Ни в одном из случаев не вызывается конструктор копирования.
Я пришел к выводу, что каждый компилятор в зависимости от своего интеллекта может или не может оптимизировать вызовы конструктора копирования в таком случае, в то время как Стандарт не требует, чтобы компилятор выполнял такую оптимизацию, каждый компилятор оценивает такие выражения в зависимости от своих возможностей.
Если я ошибаюсь, пожалуйста, добавьте мне комментарий с аргументацией.