Есть ли функция явного преобразования по умолчанию для пользовательского класса (c ++)?

Могу ли я преобразовать совместимые объекты без указателя без фактического определения оператора приведения? Итак, если B наследуется от A:

A a;
B b;

Будет ли (A)b компилироваться, если я не предоставлю собственный оператор приведения?

Изменить: похоже, он компилируется. Это потому, что существует оператор преобразования по умолчанию или компилятор распознает совместимость и использует, например, конструктор копирования по умолчанию или оператор присваивания в присваиваниях?


person user1132655    schedule 03.07.2013    source источник
comment
Вы, я не знаю, попробовали?   -  person Jan Hudec    schedule 03.07.2013
comment
Работает с моим компилятором. Но я не понимаю, как и почему это работает, как видно из моей части редактирования.   -  person user1132655    schedule 03.07.2013


Ответы (2)


Да, компилируется (http://ideone.com/CXbeh0)

По умолчанию A можно копировать. Конструктор копирования имеет подпись A::A(A const &). Поскольку экземпляр B неявно конвертируется в A const &, преобразование будет разрешено с помощью конструктора копирования A.

Преобразование в ссылку применяется и к (также неявно сгенерированному) оператору присваивания копии, поэтому a = b снова компилируется с использованием A &A::operator=(A const &).

Имейте в виду, что новый объект относится к типу A, а не B, поэтому он не содержит никакой дополнительной информации, которую содержал исходный экземпляр B. Это редко то, что вам нужно.

Кстати, в C ++ рекомендуется забыть о существовании приведения в стиле C и использовать более конкретные типы приведения в C ++:

  • Приведение в стиле функции для явного запроса на создание временного объекта целевого типа с использованием соответствующего конструктора; также позволяет использовать многопараметрические конструкторы.
  • static_cast, только для совместимых типов.
  • dynamic_cast для восходящего преобразования указателей / ссылок с проверкой во время выполнения.
  • const_cast для обработки только константы.
  • И reinterpret_cast, если вам действительно нужно поиграть с указателями, но остерегайтесь правил псевдонима.
person Jan Hudec    schedule 03.07.2013

Никакие пользовательские конструкторы или операторы не определены, тогда:

(A)b

будет реализовано так, как если бы:

A(b) //Calls A copy-constructor: A::A(const A&)

То есть он создаст временную копию A из аргумента.

Это называется объединением объектов, и обычно это плохая идея, потому что вы копируете одни поля B, а другие нет. YMMV.

person rodrigo    schedule 03.07.2013