来自虚拟课程的输出

时间:2017-06-25 01:12:26

标签: c++ c++11

下周二我有一个关于虚拟类型,继承等的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有更多问题。

非常感谢你。

1 个答案:

答案 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