C++ 堆栈对象的动态强制转换失败

C++ 堆栈对象的动态强制转换失败,c++,reference,dynamic-cast,object-slicing,C++,Reference,Dynamic Cast,Object Slicing,前几天我遇到了一个实例,其中我有一个函数获取了一个指向基类型的指针,然后我需要向上转换到一个派生类型来访问一些附加功能。但是,dynamic_cast失败了,这很奇怪,因为我的类型肯定继承了基类型 为了弄清到底发生了什么,我创建了以下测试程序,我认为它复制了我所看到的: void cast(TestClass *baseType) { if (dynamic_cast<Derived *>(baseType)) TRACE("cast was sucessfu

前几天我遇到了一个实例,其中我有一个函数获取了一个指向基类型的指针,然后我需要向上转换到一个派生类型来访问一些附加功能。但是,
dynamic_cast
失败了,这很奇怪,因为我的类型肯定继承了基类型

为了弄清到底发生了什么,我创建了以下测试程序,我认为它复制了我所看到的:

void cast(TestClass *baseType)
{
    if (dynamic_cast<Derived *>(baseType))
        TRACE("cast was sucessful");
    else
        TRACE("cast failed");
}

int main(int argc, char *argv[])
{
    Derived *test1 = new Derived();
    TestClass *test2 = new TestClass();
    TestClass test3;

    test1->identify(); // prints: this is a Derived class
    test2->identify(); // prints: this is a TestClass

    cast(test1); // succesful
    cast(test2); // fail - expected

    // reassign test2 to test1
    test2 = test1;
    test2->identify(); // prints: this is a Derived class

    cast(test2); // succesful

    // the interesting part, the test3 object (created on stack), does not cast
    // despite that it would seem possible from the cast method.
    test3 = *test1;
    test3.identify(); // prints: this is a TestClass
    cast(&test3); // fails?

    return a.exec();
}
void cast(TestClass*baseType)
{
if(动态_转换(基本类型))
TRACE(“cast成功”);
其他的
跟踪(“强制转换失败”);
}
int main(int argc,char*argv[])
{
派生的*test1=新派生的();
TestClass*test2=新的TestClass();
TestClass test3;
test1->identify();//prints:这是一个派生类
test2->identify();//打印:这是一个TestClass
cast(test1);//成功
强制转换(test2);//失败-应为
//将test2重新分配给test1
test2=test1;
test2->identify();//打印:这是一个派生类
cast(test2);//成功
//有趣的部分test3对象(在堆栈上创建)不强制转换
//尽管如此,从cast方法来看这似乎是可能的。
test3=*test1;
test3.identify();//打印:这是一个TestClass
强制转换(&test3);//失败?
返回a.exec();
}

这很有趣,因为如果您只看到我称之为
cast()
的方法,那么您可能希望可以强制转换传入的对象。我已经证明事实并非如此;这取决于对象最初是如何创建的。令人困惑的是,为什么可以强制转换一个通过引用而不是通过值重新分配的对象。此外,只要我们保证类型兼容,使用
static\u cast
会起作用吗

test3
属于
TestClass
类型(我假设它是派生类的父类),因此动态强制转换失败

即使将
*test1
分配给它,分配也只复制
TestClass
部分(aka)。将指针指定给指针时,不会发生切片

可以将衍生对象视为具有其基础的一部分:

*test1:
|--------------|
|TestClass part|
|--------------|
|Derived part  |
|--------------|

test3:
|--------------|
|TestClass part|
|--------------|
当您指定一个指针(
test2=test1
)时,对象本身不会改变,您只是通过另一个玻璃(通过指向
TestClass
的指针)来观察它,因此强制转换工作正常


当您分配一个对象本身(
test3=*test1
)时,目标(
test3
)只有一个
TestClass
对象的空间,因此副本会带走额外的
派生的
部分。

答案非常清楚。谢谢因此,一旦实例被切片,就无法“恢复”派生类型了?@user975326-正确。请注意,您可以使用引用而不是类型,在这方面它的作用类似于指针,但语法与使用堆栈分配的对象时相同。