基类指向派生类型的指针

时间:2013-04-23 03:00:48

标签: c++ pointers polymorphism

所以我一直试图围绕演员。在其他语言中,我见过像

这样的代码
Player player = (DifferentObject as Player)

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

A* a = new B();

每当我想调用B函数时,我都需要进行投射。

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

3 个答案:

答案 0 :(得分: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'是多态类型并且至少有一个虚拟成员函数。

答案 1 :(得分:2)

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

如果需要通过基类指针调用特定于派生类的方法,那么是的,你需要显式强制转换。如果类是多态的,最好使用dynamic_cast。但请注意,如果您需要经常这样做,那么您可能会错过设计中的某些内容,并且必须重新审视设计。

答案 2 :(得分: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;