动态转换c ++有问题

时间:2013-10-22 22:50:39

标签: c++

我正在尝试编写一个简单的程序,作为在基类对象和派生类对象之间来回转换的演示。这是我的代码

#include "stdafx.h"
#include <iostream>

using namespace std;

class a
{
    virtual void hi(){}
};

class b : public a
{
};

int main()
{
    a abs = b();
    b& bbs = dynamic_cast<b&>(abs);
    while(true);
}

代码编译正常,但是当我运行它时,我在类Tests.exe中的0x75C4C41F处获得“未处理的异常:Microsoft C ++异常:std :: bad_cast在内存位置0x003DF908。”我看不出我做错了什么。任何人都可以向我解释为什么这不起作用。

4 个答案:

答案 0 :(得分:6)

你遇到了一个叫做“切片”的C ++问题。基本上,absa,而不是b,因为声明

a abs = b();
  1. 创建新的b对象。
  2. 查找a构造函数,其中b找到a的复制构造函数(基于从ba的隐式转换)。
  3. 将新的b对象转换为a(通过丢弃特定于b的部分)并将其传递给a的复制构造函数。
  4. 如果您需要以多态方式复制对象(可能是实际代码中实际需要的对象),那么执行此操作的典型方法是执行以下操作:

    class a
    {
    public:
        virtual a *clone() { return new a(*this); }
    };
    
    class b
    {
        virtual a *clone() { return new b(*this); }
    };
    
    b my_b;
    a *abs = my_b.clone();
    

    同样,不确定这是否是你在这种情况下所需要的,但它确实存在。

答案 1 :(得分:3)

您的代码有错误。 absa类型的对象,是从b的匿名实例构建的副本。您需要的是b的一个实例,并使abs成为对a的引用。

b bbs;
a &abs = bbs;
b &bbr = dynamic_cast<b&>(abs);

你应该在a中定义一个虚拟析构函数,因为你想使用多态(虽然这个例子不需要)。

答案 2 :(得分:1)

你无法动态投射一个物体。您只能投射引用或指针。

将其更改为

a* abs = new b();
b* bbs = dynamic_cast<b*>(abs);

b obj_b = b();
a& abs = obj_b;
b& bbs = dynamic_cast<b&>(abs);

答案 3 :(得分:1)

这样的事情可能就是你想要做的事情:

#include <iostream>

class a
{
    public:
        virtual void hi(){}
        virtual ~a() {}
};

class b : public a
{
};

int main()
{
    b b_obj;
    a& a_ref_to_b = b_obj;
    b& b_ref_to_b = dynamic_cast<b&>(a_ref_to_b);
    return 0;
}