Я сейчас читаю Скотта Мейерса «Более эффективный С ++». Назиданию! В пункте 2 упоминается, что dynamic_cast может использоваться не только для даункастов, но и для приведений братьев и сестер. Может ли кто-нибудь предоставить (разумно) необдуманный пример его использования для братьев и сестер? Этот глупый тест печатает 0, как и должно быть, но я не могу представить себе какое-либо приложение для таких преобразований.
#include <iostream>
using namespace std;
class B {
public:
virtual ~B() {}
};
class D1 : public B {};
class D2 : public B {};
int main() {
B* pb = new D1;
D2* pd2 = dynamic_cast<D2*>(pb);
cout << pd2 << endl;
}
Предлагаемый вами сценарий не соответствует sidecast точно, который обычно используется для приведения между указателями / ссылками двух классов, а указатели / ссылки ссылаются на объект класса, который оба является производным от этих двух классов. Вот пример для этого:
struct Readable {
virtual void read() = 0;
};
struct Writable {
virtual void write() = 0;
};
struct MyClass : Readable, Writable {
void read() { std::cout << "read"; }
void write() { std::cout << "write"; }
};
int main()
{
MyClass m;
Readable* pr = &m;
// sidecast to Writable* through Readable*, which points to an object of MyClass in fact
Writable* pw = dynamic_cast<Writable*>(pr);
if (pw) {
pw->write(); // safe to call
}
}
Это называется кросс-бросок, и он используется, когда класс наследует от двух разных классов (не наоборот, как показано в вашем вопросе).
Например, с учетом следующей иерархии классов:
A B
\ /
C
Если у вас есть A
указатель на C
объект, то вы можете получить B
указатель на это C
объект:
A* ap = new C;
B* bp = dynamic_cast<B*>(ap);