我意识到当我不想更改/构建外部库时调试代码时,此方法特别有用。
我还没有用这个烧手,还是至少可以安全调试?
#include <iostream>
using namespace std;
class A
{
public:
A(int lx):x(lx){};
protected:
int x;
};
class B : public A
{
public:
void print(){std::cout << x << endl;}
};
int main() {
A *a = new A(22);
B *b = static_cast<B*>(a);
b->print();
}
编辑:如果使用我使用reinterpret_cast而不是static_cast,并确保B没有任何虚拟方法,A和B的内存是否匹配,它不会是UB吗?
答案 0 :(得分:3)
不,这不安全,事实上它是undefined behavior(见子弹2 here)。如果要将基指针强制转换为派生指针,则应使用dynamic_cast
,因为如果转换无效,则会返回nullptr
。
答案 1 :(得分:3)
您的代码具有未定义的行为,但由于它非常简单,您可以通过检查中间汇编代码或反汇编的二进制文件来说服自己是否可以处理您的实现。
很有可能它会在实践中发挥作用,特别是对于简单的课程。对这些&#34;主要的恐惧看起来它应该工作,即使它是UB&#34;情况是,优化器会根据它有权做出的假设做出一些非常聪明的推论,但对你的UB代码来说并不是真的。因此,关闭所有优化会让您更好地看到(dis)汇编(a)完成您的预期和(b)您可以理解。
至少对于这个例子,您可以通过复制来访问x
的值以进行调试而没有未定义的行为,也无需修改类A
:
class B : public A
{
public:
B(const A&a) : A(a) {}
void print(){std::cout << x << endl;}
};
int main() {
A *a = new A(22);
static_cast<B>(*a).print();
}