下周二我有一个关于虚拟类型,继承等的C ++测试。我的问题是我的代码中有一个奇怪的输出,我不知道它来自哪里:
代码:
#include <iostream>
#include <typeinfo>
using std::cout; using std::endl;
template<int id> class B{
int* p;
public:
B(): p{new int}{
cout << typeid(*this).name() << "::" << typeid(*this).name() << "()" << endl;
}
B(const B& b): p{new int{*(b.p)}}{
cout << typeid(*this).name() << "::" << typeid(*this).name() << "(const " << typeid(*this).name() << "&)" << endl;
}
virtual ~B(){
delete p;
cout << typeid(*this).name() << "::~" << typeid(*this).name() << "()" << endl;
}
};
class D: public B<0>{
public:
D(){
cout << "D::D()" << endl;
}
D(const D& d): B<0>{static_cast<const B&>(d)}, b1{d.b1}, b2{d.b2}{
cout << "D::D(const D&)" << endl;
}
~D(){
cout << "D::~D()" << endl;
}
private:
B<1> b1;
B<2> b2;
};
int main()
{
B<0>& b{*new D};
cout << "-----------------------------" << endl;
D d{dynamic_cast<D&>(b)};
cout << "-----------------------------" << endl;
delete &b;
cout << "-----------------------------" << endl;
}
输出:
1BILi0EE::1BILi0EE()
1BILi1EE::1BILi1EE()
1BILi2EE::1BILi2EE()
D::D()
-----------------------------
1BILi0EE::1BILi0EE(const 1BILi0EE&)
1BILi1EE::1BILi1EE(const 1BILi1EE&)
1BILi2EE::1BILi2EE(const 1BILi2EE&)
D::D(const D&)
-----------------------------
D::~D()
1BILi2EE::~1BILi2EE()
1BILi1EE::~1BILi1EE()
1BILi0EE::~1BILi0EE()
-----------------------------
D::~D()
1BILi2EE::~1BILi2EE()
1BILi1EE::~1BILi1EE()
1BILi0EE::~1BILi0EE()
问题:
1)为什么每个typeid的名字都如此奇怪?有没有办法计算每一个?我想出如果我改变我的编译器,名称也会改变。
2)为什么我的程序从B基类打印两次析构函数的输出。它与虚拟类型和继承有关吗?
3)有人可以解释一下使用static_cast而不是dynamic_cast的好处吗?从我所教授的每个角度来看,static_cast在执行时间上通常比dynamic_cast有更多问题。
非常感谢你。
答案 0 :(得分:1)
有人可以向我解释使用
static_cast
代替dynamic_cast
的好处吗?从我所教授的每个角度来看,static_cast
执行时间与dynamic_cast
相比通常会遇到更多问题。
static_cast
的好处是它的成本较低,但是,它有更多问题。
采取以下简单程序:
#include <iostream>
#include <typeinfo>
struct Foo
{
virtual ~Foo () {}
};
struct Bar1 : Foo
{
Bar1(int v) : v_(v) {}
int v_;
};
struct Bar2 : Foo
{
Bar2(double v) : v_(v) {}
double v_;
};
void test_static_cast(Foo& f)
{
std::cout << static_cast<Bar1&>(f).v_ << std::endl;
}
void test_dynamic_cast(Foo& f)
{
std::cout << dynamic_cast<Bar1&>(f).v_ << std::endl;
}
int main()
{
Bar1 b(10);
test_static_cast(b);
test_dynamic_cast(b);
}
无论您使用的是static_cast
还是dynamic_cast
,输出都是相同的。但是,如果您将main
更改为使用Bar2
而不是Bar1
,
int main()
{
Bar2 b(10);
test_static_cast(b);
test_dynamic_cast(b);
}
static_cast
版本进入未定义行为的区域,而dynamic_cast
版本引发std::bad_cast
异常。您可以以可预测的方式处理异常,而static_cast
版本没有可预测的行为。
仅在非常您正在处理的内容时使用static_cast
。否则,请选择更昂贵但更可靠的dynamic_cast
。