0

I'm trying to figure out why b->boo() actually calls a.far().
is the multiple inheritance from template class and general class forbidden? why does the inherit order matter? The code is here:

#include <iostream>

template <int somecount>
class inner_parent_class
{
public:
    int array[somecount];
    virtual void far() = 0;
};

class any_class
{
public:
    virtual void boo() = 0;
};

template <int somecount>
class child_class_bad : public inner_parent_class<somecount>, public any_class
{
public:
    virtual void boo() override
    {
        std::cout << "call me" << std::endl;
    }

    virtual void far() override
    {
        std::cout << "do not call me" << std::endl;
    }
};

template <int somecount>
class child_class_good : public any_class, public inner_parent_class<somecount>
{
public:
    virtual void boo() override
    {
        std::cout << "call me" << std::endl;
    }

    virtual void far() override
    {
        std::cout << "do not call me" << std::endl;
    }
};

int main()
{
    {
        child_class_good<32> a;
        any_class* b;
        auto c = dynamic_cast<void*>(&a);
        b = reinterpret_cast<any_class*>(c);
        b->boo();
    }
    {
        child_class_bad<32> a;
        any_class* b;
        auto c = dynamic_cast<void*>(&a);
        b = reinterpret_cast<any_class*>(c);
        b->boo();
    }

    return 0;
}

@ GCC 9.3.0

@ VS 2019 16.5.3

I suppose that both child classes (child_class_good and child_class_bad) are different classes even though their class names are the same, because they are template classes and constructed separately at compiled time. Nevertheless, each class might have its own v-table, so I think calling boo() as their common parent class any_class should correctly work.

4

1 回答 1

3

reinterpret_cast不能用来做你想做的事。reinterpret_cast从 avoid*到 a 的A仅在给定的指针是指向类型对象的指针T*时才产生指向有效T*的指针。void*T

执行 adynamic_cast<void*>(p)返回void*指向 指向的最派生对象的a p。由于您&a实际上是它指向的派生最多的对象,因此它只是将指针转换为 a void*

然后你执行reinterpret_cast<any_class*>那个void*void*指向child_class_good<32>或类型的对象child_class_bad<32>。你的演员是说指针实际上指向一个any_class. 这是不正确的(这两种类型都不是标准布局,因此未定义基类的布局),因此尝试使用结果将产生未定义的行为。

您确定为的情况与 ;good一样无效bad。它只是碰巧起作用。

目前尚不清楚您为什么要尝试做您想做的任何事情,但是没有有效的方法可以void*指向未知类型的最派生对象并将其转换为任何有用的对象。为了使用 a void*,您必须知道用于生成它的确切类型void*

于 2020-05-04T02:12:55.440 回答