簡體   English   中英

多態性確定問題

[英]Polymorphism determination issue

我有一個問題,我正在努力。 我有一個數字類,在這種模式中相互繼承:

#include <stdio.h>
#include <stdlib.h>

#include <list>

class TimeObject
{
  public:
    virtual void Tick()=0;

    std::list<TimeObject*> ticks;
};

class MapObject : public TimeObject
{
  public:
    MapObject()
    {
        ticks.push_front(this);

        printf("Create MapObject %p\n", this);
    }

    void Tick() { printf("mapobject tick\n"); }
};

class ControlObject : public MapObject
{
  public:
    ControlObject()
    {
        ticks.push_front(this);

        printf("Create ControlObject %p\n", this);
    }

    void Tick() { printf("controlobject tick\n"); }
};

int main()
{
    ControlObject test;

    std::list<TimeObject*>::iterator it = test.ticks.begin();

    for(; it != test.ticks.end(); it++)
    {
        TimeObject *trigger = *it;

        trigger->Tick();
    }

    return 0;
}

示例中的列表存儲任何TimeObject派生類。 我的問題是,當在列表中存儲也是ControlObjects MapObject指針時,調度總是選擇ControlObject函數。

是否可以使用多態來使用ControlObject指針觸發MapObject函數? 如果不可能/實用,什么是一個好的選擇?

您應始終將指針存儲到列表中的基類A*std::list< A*> )。
在將指針添加到容器之前,應該正確地指針指向類型為BC的對象。
一旦你這樣做,動態調度將負責根據實際的對象類型為你調用正確的函數。 你不需要做任何事情。

我不知道為什么你想要任何其他的設計,如果你有任何理由這樣做,請告訴我們。

為什么它總是在代碼中調用ControlObject::tick()
你打電話時:

ticks.push_front(this); 

ControlObject::ControlObject()你最終會覆蓋你添加到列表中的第一個指針,第一個推送指針的類型不再是MapObject *它是ControlObject *因為你改變了它后面的指針。你沒有轉移指向列表的指針的所有權,但您都擁有共享所有權,並通過派生類中的構造函數調用修改了列表中的對象。 這會在列表中留下兩個ControlObject *對象,動態分派正確地確定並調用正確的方法。

動態調度沒有什么問題,這是正確的行為。
如果要調用MapObject::Tick(); 那么你將明確地告訴編譯器這樣做,動態調度適用於實際類型的對象並且它正常工作。

void controlobject::Tick() 
{ 
    printf("controlobject tick\n"); 
    MapObject::Tick();
}

復制評論:

我擔心這是一個糟糕的設計。代碼工作正常,它按照C ++標准的定義。問題在於設計。除非你提供你想要在更廣泛意義上實現的細節,對新設計進行推測是困難而且毫無意義的。

在類型C的變量上使用對類型B的強制轉換應該可以解決問題。

   C c;
   B b;
   c.Function();
   ((B)c).Function();
   A * l[] = {&c,&b,&c};
   l[0]->Function();
   l[1]->Function();
   l[2]->Function();

   B test = *(B*)l[0];
   test.Function();

在您當前的示例中,您應該能夠通過在ControlObject::Tick()調用MapObject::Tick()來調用兩個虛擬成員(或者只是一個取決於底層類型的成員ControlObject::Tick()

class ControlObject : public MapObject
{
  public:
    ControlObject()
    {
        ticks.push_front(this);

        printf("Create ControlObject %p\n", this);
    }

    void Tick() { printf("controlobject tick\n"); MapObject::Tick(); }
};

顯式函數調用表示法是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM