Нет вызова конструктора копирования

Рассмотрим заданный код

struct ABC
{
    ABC()
    {
        std::cout<<" Calling from default constructor";
    }

    ABC(const ABC &copy)
    {
        std::cout<<"Calling from copy constructor";
    }
};

int main()
{
    ABC abc = ABC();
}

У меня есть два вопроса


Q1) Удаление const из объявления параметра конструктора копирования дает ошибку. Почему?

Q2) После добавления ключевого слова const я не вижу вызов конструктора копирования. Зачем? Конструктор копирования не вызван так, зачем нужен констант?


ТИА

Ответ 1

  • Вам нужен константа, потому что вы пытаетесь инициализировать abc с помощью временной ABC(), которая является константой. Следовательно, если конструктор не const, компилятор должен отклонить код.

  • После того, как вы сделаете это, код будет стандартной жалобой, и компилятор сможет его скомпилировать. Однако это позволило оптимизировать копию в этом случае, как указано в стандарте, поэтому он удаляет вызов конструктору копирования.

Ответ 2

Q1) Удаление const из копии объявление параметра конструктора дает ошибку. Почему?

ABC abc = ABC();

эквивалентно

ABC abc((ABC()));

Поскольку вы передаете временный объект в конструктор копирования, он может связываться только с ссылками на const, а не с неконстантными ссылками.

Конструктор копирования может принимать неконстантные ссылки (например, std::auto_ptr), но это означает, что их использование более ограничено.

Q2) После добавления ключевого слова const я не видите вызов копии конструктор. Зачем? Конструктор копирования не называется так, так почему const необходимо?

В данном сценарии компилятору разрешено оптимизировать избыточные вызовы для конструктора. Зачем создавать объект по умолчанию только для его копирования, если он может просто вызвать конструктор по умолчанию?

Однако, даже если вызовы конструктора копирования оптимизированы, компилятор должен проверить, что код будет действительным, как записано, - как если бы конструкция копирования не была оптимизирована.

Ответ 3

Константа необходима, поскольку вам не разрешено привязывать временную ссылку к неконстантной ссылке. Несмотря на то, что компилятор оптимизирует конструктор копирования, то есть только до последнего этапа.

Стандарт С++ 0x обращается к этому с добавлением ссылок rvalue. который позволит вам отбросить параметр const к неконстантическому...

ABC( ABC&& copy) 

Хотя вам все равно нужен стандартный конструктор ссылок...

Ответ 4

Если вы также определяете оператор присваивания, вы увидите, что даже тот, который не вызван: компилятор оптимизирует ABC abc = ABC(); в ABC abc;, так как они имеют одинаковую семантику.

О других сомнениях, g++ не жалуется на объявление параметра конструктора копии как неконстантного (даже с -Wall -W -std=c++98). В любом случае, не проверял стандарт.