Результат выражения dynamic_cast<T>(v) - это результат преобразования выражения v в тип T. T должен быть указателем или ссылкой на полный тип класса, или «указателем на cv void». dynamic_cast Оператор не должен cast away constness.
Если T это тип указателя, v должно быть prvalue указателя на полный тип класса, а результатом будет prvalue типа T. Если T - ссылочный тип lvalue, v должен быть lvalue полного типа класса, а результатом будет lvalue типа, на который ссылается T. Если T это ссылочный тип rvalue, v должно быть glvalue, имеющее полный тип класса, а результатом будет значение x того типа, на который ссылается T.
Если тип v такой же Tили такой же, T за исключением того, что тип объекта класса в T более cv-квалифицирован, чем тип объекта класса в v, результат будет v (при необходимости преобразован).
Если значение v является значением нулевого указателя в случае указателя, результатом является значение нулевого указателя типа T.
Если T это «указатель на cv1 B» и v имеет тип «указатель на cv2 D», то B есть базовый класс D, результатом является указатель на уникальный B подобъект D объекта, на который указывает v. Точно так же, если T это «ссылка на cv1 B» и v имеет cv2 D такой тип , который B является базовым классом D, результатом является уникальный B подобъект D объекта, на который ссылается v.69 Как в случае указателя, так и в случае ссылки, программа плохо сформирована, если cv2 имеет более высокую квалификацию cv, чем недоступный или неоднозначный базовый класс cv1 или если он B является D. [ Example:
struct B { };
struct D : B { };
void foo(D* dp) {
B* bp = dynamic_cast<B*>(dp); // equivalent to B* bp = dp;
}
— end example ]
Если T это «указатель на cv void», то результатом является указатель на самый производный объект, на который указывает v. В противном случае применяется проверка времени выполнения, чтобы увидеть, может ли объект, на который указывает или на который ссылается, v быть преобразован в тип, на который указывает или на который ссылается T.
Если C это тип класса, на который T указывает или ссылается, проверка времени выполнения логически выполняется следующим образом:
Если в наиболее производном объекте, на который указывает (упоминается) v, v указывает (ссылается) на public подобъект базового класса C объекта, и если только один объект типа C является производным от подобъекта, на который указывает (ссылается) v результирующие точки (ссылается ) к этому C объекту.
В противном случае, если v указывает (ссылается) на public подобъект базового класса самого производного объекта, а тип самого производного объекта имеет базовый класс типа C, который является однозначным, и publicрезультат указывает (ссылается) на C подобъект самый производный объект.
В противном случае проверка времени выполнения fails.
Значение неудачного приведения к типу указателя - это значение нулевого указателя требуемого типа результата. Неудачное приведение к типу ссылки throws an exception на тип, который соответствует handler типу std::bad_cast.
class A { virtual void f(); }; class B { virtual void g(); }; class D : public virtual A, private B { }; void g() { D d; B* bp = (B*)&d; // cast needed to break protection A* ap = &d; // public derivation, no cast needed D& dr = dynamic_cast<D&>(*bp); // fails ap = dynamic_cast<A*>(bp); // fails bp = dynamic_cast<B*>(ap); // fails ap = dynamic_cast<A*>(&d); // succeeds bp = dynamic_cast<B*>(&d); // ill-formed (not a runtime check) } class E : public D, public B { }; class F : public E, public D { }; void h() { F f; A* ap = &f; // succeeds: finds unique A D* dp = dynamic_cast<D*>(ap); // fails: yields null; f has two D subobjects E* ep = (E*)ap; // ill-formed: cast from virtual base E* ep1 = dynamic_cast<E*>(ap); // succeeds }
— end example ] [ Note: [class.cdtor] описывает поведение, dynamic_cast применяемое к строящемуся или разрушающемуся объекту. ] — end note
Указанный most derived object или упомянутый by v может содержать другие B объекты в качестве базовых классов, но они игнорируются.