2

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

#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++ 异常:内存位置 0x003DF908 处的 std::bad_cast”。我没有看到我做错了什么。谁能向我解释为什么这不起作用。

4

4 回答 4

6

您遇到了一个称为“切片”的 C++ 问题。基本上, absis an a, not a b, 因为语句

a abs = b();
  1. 创建一个新b对象。
  2. 查找接受 a的a构造函数b,并找到a(基于从bto的隐式转换a)的复制构造函数。
  3. 将新b对象转换为a(通过丢弃特定于 的部分b)并将其传递给 的复制构造函数a

如果您需要以多态方式复制对象(这可能是您实际代码中实际需要的,也可能不是),典型的方法是执行以下操作:

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();

同样,不确定在这种情况下这是否是您所需要的,但确实如此。

于 2013-10-22T22:59:38.510 回答
3

您的代码有错误。abs是类型的对象a,并且是从 的匿名实例复制构造的b。您需要的是 a 的一个实例babs引用a.

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

您应该定义一个虚拟析构函数,a因为您想使用多态性(尽管本示例不需要它)。

于 2013-10-22T22:59:11.760 回答
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);
于 2013-10-22T22:57:06.950 回答
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;
}
于 2013-10-22T23:00:14.637 回答