你可以使用它而不仅仅是向下投射 - 你可以侧身或甚至向上投射另一个链。 dynamic_cast将寻找所需的对象并在可能的情况下返回它。
那么这究竟意味着什么,以及发生这种情况的限制/条件是什么。
我认为这就是声明的含义。演员阵容发生了,我也得到了一个明显的分段错误。
#include <iostream>
class base
{
public:
virtual void print () = 0;
};
class childa : public base
{
public:
char c1;
virtual void print ()
{
std::cout << "childa\n";
}
void printout()
{
std::cout << "childa out\n";
}
};
class childb : public base
{
public:
int c2;
virtual void print ()
{
std::cout << "childb\n";
}
void printin()
{
std::cout << "childb in\n";
}
void printout()
{
std::cout << "childb out\n";
}
};
int main()
{
base* b = new childa;
b ->print();
dynamic_cast<childa*>(b)->printout();
dynamic_cast<childb*>(b)->printout(); // cast happens here and the output is printed
dynamic_cast<childa*>(b)->c1 = 'a';
dynamic_cast<childb*>(b)->c2 = 2; // segfault here
}
这是我得到的输出并发生了段错误
childa
孩子出去了 孩子出去进程返回-1073741819(0xC0000005)执行时间:5.844 s
按任意键继续。
编辑: 是的,我不检查空值是多么愚蠢。 但我想更多地了解其他问题(上/下/侧身)的评论
答案 0 :(得分:5)
你在这里遇到未定义的行为:
dynamic_cast<childb*>(b)->printout();
强制转换实际上失败了(返回空指针)。您永远不会检查返回值并通过它调用成员函数。这是未定义的行为,任何事情都可能发生。在你的情况下,似乎因为函数不以任何方式访问this
,即使通过空指针调用它也会执行得很好。但这并不能保证。
至于横向演员(或构建另一个链)是什么,需要更复杂的继承层次来证明:
struct base1
{
virtual ~base1() {}
};
struct base2
{
virtual ~base2() {}
};
struct child1 : base1
{};
struct child2 : base2
{};
struct both : child1, child2
{};
int main()
{
child1 *c1 = new both();
static_cast<base1*>(c1); // ok
static_cast<both*>(c1); // ok
static_cast<child2*>(c1); // compile-time error, unrelated types
dynamic_cast<child2*>(c1); // succeeds, because the object is actually of type `both`, i.e. derived from `child2`; cast sideways
static_cast<base2*>(c1); // compile-time error, unrelated types
dynamic_cast<base2*>(c1); // succeeds, because the object is actually of type `both`, i.e. derived from `base2`; cast up another chain
base1 *b1 = new child1();
static_cast<child1*>(b1); // ok
static_cast<both*>(b1); // compiles, but produces UB, as the object is not of correct type
static_cast<base2*>(b1); // compile-time error, unrelated types
dynamic_cast<base2*>(b1); // fails (returns null pointer), because the object is not actually derived from `base2`.
}
答案 1 :(得分:0)
dynamic_cast<T*>(a)
是T*
的实例时, *a
才会返回非空T
;否则,它返回NULL
。
从空指针调用方法或属性会产生未定义的行为。
答案 2 :(得分:0)
dynamic_cast的用处在他的回答中。使用此代码
int main()
{
base* b = new childa;
b ->print();
childa* testA = dynamic_cast<childa*>(b);
if (testA)
{
//Here you can be sure that your object is right
testA->printout();
testA->c1 = 'a';
}
else
std::cout << "Error casting b to testA" << std::endl;
childb* testB = dynamic_cast<childb*>(b);
if (testB)
{
//Here you can be sure that your object is right
testB->printout();
testB->c2 = 2;
}
else
std::cout << "Error casting b to testB" << std::endl;
}
您获得以下输出
childa
childa out
Error casting b to testB