0

所以我一直在努力解决演员阵容。在其他语言中,我见过类似的代码

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);
}
4

3 回答 3

3

在调用成员函数时,您不需要使用这样的强制转换。当您实例化时,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”是一种多态类型并且至少有一个虚成员函数。

于 2013-04-23T03:03:33.333 回答
2

如果您需要一种行为,其中每个类都需要为方法提供自己的实现,那么您需要将这些函数放在基类中并将它们标记为virtual,每个派生类都应覆盖这些方法。这允许您根据具体情况调用适当的方法具体的对象类型而不是指针。

如果您需要通过基类指针调用特定于派生类的方法,那么是的,您确实需要显式转换。dynamic_cast如果类是多态的,最好使用 a 。但请注意,如果您需要经常这样做,那么您可能在设计中遗漏了一些东西,您必须重新审视设计。

于 2013-04-23T03:07:44.857 回答
2

不是没有明确的演员表吗?

如果您使用基类指针调用虚函数,则不需要使用显式强制转换。它在运行时根据基类指针指向的对象类型来决定。

如果你调用的是非虚函数,那么如果你将派生类对象赋值给基类指针,如果你需要调用派生类的非虚函数,你需要强制转换。

以上应解释以下结果:

A* a = new B(); //don't miss ; 
//you use base class pointer to point to derived class object
((B*)a)->b_only_func();              
//identical - prints Hello. b_only_func is not virtual, 
//you need cast in order to really call B's function, 
//otherwise, you will get compile error since 
//b_only_func() is not a member of a
a->a_only_func();    // prints a only func.
a->a_virtual_func();   // prints derived. this is expected because of polymorphism
((B*)a)->a_virtual_func();           // prints derived, not needed in this case
delete a;
于 2013-04-23T03:11:47.603 回答