c++ - 指向派生类型的基类指针

标签 c++ pointers polymorphism

所以我一直在努力解决石膏问题。在其他语言中,我见过这样的代码

Player player = (DifferentObject as Player)

尤其是多人游戏时。我的问题是,如何在 C++ 中复制这种代码?如果我使用

A* a = new B();

每当我想调用 B 函数时,我都需要转换 a。

struct A
{
    A() { }
    virtual ~A() { }

    void a_only_func() const
    {
        std::cout << "a only func." << std::endl;
    }

    virtual void a_virtual_func() const
    {
        std::cout << "a virtual func." << std::endl;
    }
};

struct B : public A
{
    B() { }
    ~B() { }

    void b_only_func() const
    {
        std::cout << "Hello." << std::endl;
    }

    void a_virtual_func() const
    {
        std::cout << "derived." << std::endl;
    }
};

int main()
{
    A* a = new B()
    ((B*)a)->b_only_func();              /* identical - prints Hello.
    (static_cast<B*>(a))->b_only_func();  * identical */
    a->a_only_func();                    // prints a only func.
    a->a_virtual_func();                 // prints derived.
    ((B*)a)->a_virtual_func();           // prints derived
    delete a;
    return 0;
}

如您所见,一切都按预期进行。但并非没有明确的类型转换。我在这里错过了一些微妙的东西吗?

更新

以下似乎代表了我正在寻找的成语。

void do_stuff(Player* player)
{
    DerivedPlayer localVar = dynamic_cast<DerivedPlayer*>(player);
}

最佳答案

调用成员函数时不需要像那样使用强制转换。当您实例化 B 时,您可以将其分配给 B* 类型的变量,并且仍然调用在“A”和“B”中声明的函数

B *b = new B();

b->b_only_func();     // identical - prints Hello.
b->b_only_func();     // identical
b->a_only_func();     // prints a only func.
b->a_virtual_func();  // prints derived.
b->a_virtual_func();  // prints derived

如果您需要保留指向基类 A 的指针,您可以使用 dynamic_cast 来检索指向派生类的指针。

A* a = new B();

B* b = dynamic_cast<B*>(a);

如果变量 a 不是从类型 B 派生的,则 dynamic_cast 将返回 NULL

if(b == NULL)
{
   // a is not derived from type 'B'
}

这要求“A”是多态类型并且至少有一个虚拟成员函数。

关于c++ - 指向派生类型的基类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16160166/

相关文章:

c++ - memset 导致 std::string 赋值崩溃

c++ - System::Currency 和 C++ Builder

c++ - 值调用和指针引用调用

c++ - 在这种情况下是否存在内存泄漏?

c++ - C++17 中纯虚函数的主体?

c++ - C++11 中的几个数组

c++ - 微雪电子纸ESP32板HTTP客户端管理问题

ios - 如何将 __autoreleasing 地址保留为类中的强属性?

c++ - 如果重写的 C++ 函数调用父函数,父函数调用另一个虚函数,那么调用的是什么?

c# - 如何调用base.base.method()?