Если вы хотите, чтобы сделать переход от типа A
к B
, у вас есть два синтаксиса, чтобы определить преобразование:
class B
{
public:
B(A); # Conversion constructor.
};
или
class A
{
public:
operator B(); # Conversion operator.
};
Для случая, как:
void f(B b);
int main()
{
A a;
f(a);
}
Если существует первая версия, она создает временный объект класса s B
, используя a
как параметр. Если вторая версия существует (и вы ее реализуете, конечно), она вызывает operator B()
класса A
для создания объекта типа B
от a
. Если они существуют, компилятор выдает сообщение об ошибке двусмысленности.
О путях/повышающих каскадах, неявные преобразования позволяют повышать уровень (если исходные и целевые типы являются ссылками/указателями), даже если целевая база является неотъемлемым (частным) базовым классом источника. Неявные преобразования также позволяют преобразовать из неконстантного исходного типа в целевой тип const, а также преобразовать из rvalue в lvalue и так далее.
Это, короче говоря, правила неявных преобразований. Более полное руководство (с учетом встроенных и пользовательских типов и встроенных преобразований) - here.
Если вы используете C++ - литье:
f(static_cast<B>(a));
его почти то же самое, но с некоторыми отличиями: если B
является innaccesible (частная) база a
, бросок не допускается. Другая разница заключается в том, что downcasting разрешен без проверки времени выполнения (если B
является производным классом A
, он позволяет выполнять кастинг, даже если a
на самом деле не является объектом типа B
). Это допустимо, потому что проверка времени выполнения медленная, поэтому, если вы знаете, что a
действительно имеет тип B
, вы можете безопасно применять кастинг без проверки времени выполнения.
Других отливок:
const_cast<B>(a)
Только для перехода от сопзИ к неконстантным и наоборот.
reinterpret_cast<B>(a);
Бросьте все. Почти никаких правил. Если конверсия из a
в B
не существует, она просто занимает область памяти a
и возвращает ее как объект типа B
. Его самый быстрый бросок живой.
dynamic_cast<B>(a);
Даунсайдинг с проверкой времени выполнения (оба типа должны быть ссылками или указателями). Если реальный тип a
не является B
(даже базовый класс реального типа a
), исключение или нулевой указатель выбрасывается/возвращается (в соответствии с тем, если или B
являются ссылками или указателями).
Наконец, C-литье:
f((B)a);
Что C-литейный это попробовать различные отливки (кроме dynamic_cast
, а также позволяет приведение к innacesible базовых классов) и использовать первый, который работает. Я бы сказал, что C-casting так же мощен, как и неявный литье.
Явный отливка с синтаксисом несильно вызова:
f(B(a));
эквивалентно C-кастинг в поведении.
Вы также можете написать 'A a = foo (10);' – emlai
Возможный дубликат [Когда должен использоваться статический \ _cast, dynamic \ _cast, const \ _cast и reinterpret \ _cast?] (Http: // stackoverflow. com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used) –
@zenith Конечно, в этом случае я могу. Но часто бывает, что конструктор «явный». – stella