为什么这段代码不将基类转换为c ++中的派生类?

G. *_*age 2 c++

为什么此C ++代码不起作用?它旨在将基类动态转换为派生类。我将如何实现?

    class base {
    public:
        int x = 0;
    };

    class a : public base {
    public:
        char c = 'a';
    };

    class b : public base {
    public:
        long int d = 'b';
    };

    std::vector<base> vec;
    for (int i = 0; i < 5; i++) {
        b temp;
        vec.push_back(temp);
    }

    for (int i = 0; i < 5; i++) {
        b* temp = (b*)&vec[i];
        std::cout << temp->d << std::endl;
    }
Run Code Online (Sandbox Code Playgroud)

abh*_*ora 7

每当您将一个对象推b入Objects的向量vec中时Base,就会创建另一个temp纯粹是type的对象base。您可能会认为(并且您是不对的!)存储在其中的元素vector将是Base类型,但是它将保存一个类型的对象,b但这不是您Dynamic Polymorphism在C ++中的实现方式。

声明:

std::vector<Base> vec; // 1
b temp;                // 2
vec.push_back(temp);   // 3
Run Code Online (Sandbox Code Playgroud)

第三行将Base通过调用基类的赋值运算符来创建要键入的不同对象Base operator=(const Base& )

此外,这b* temp = (b*)&vec[i];是未定义的行为,因为您正在明确尝试将指向的对象的指针强制转换base为其派生类类型的b对象,但它不保存类型的对象,b因此,您可能会得到意外的行为。

注意:

使用dynamic_cast在基类和派生类之间进行转换,因为这将确保转换有效。否则,它将返回nullptr。但是,您需要通过至少具有1个虚函数使您的基类多态。

如果转换成功,则dynamic_cast返回类型为new-type的值。如果强制转换失败并且new-type是指针类型,则它将返回该类型的空指针。如果强制转换失败并且new-type是引用类型,则它将引发与std :: bad_cast类型的处理程序匹配的异常。

解:

使用指针矢量进行base分类以实现运行时多态。

std::vector<base *> vec;
for (int i = 0; i < 5; i++) {
    b *temp = new b();
    vec.push_back(temp);
}

for (int i = 0; i < 5; i++) {
    b* temp = dynamic_cast<b *>(vec[i]); // For dynamic cast, you need to add virtual functions to your base class
    if (temp != nullptr)
        std::cout << temp->d << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

对象切片也可以解决您的问题Object Slicing是这类问题的正确关键词。这是对象切片的定义

对象派生发生在将派生类对象分配给基类对象时,派生类对象的其他属性被切分以形成基类对象。

我在下面的链接中引用了答案之一。有关某些代码段的最佳解释和可能的解决方案,请参见此答案答案。参见本文,它解释了在基类的向量中推送Derived类的对象时的问题。

在“切片”中,您将派生类的对象分配给基类的实例,从而丢失了部分信息-其中一些信息被“切片”了。

例如,

class A {
   int foo;
};

class B : public A {
   int bar;
};
Run Code Online (Sandbox Code Playgroud)

因此,类型B的对象具有两个数据成员foo和bar。

然后,如果您要编写此代码:

B b;
A a = b;
Run Code Online (Sandbox Code Playgroud)

然后,b中有关成员栏的信息丢失在a中。