2016-07-22 78 views
-2

我有一羣快樂的人。 每個快樂的人都有一個名爲updateHappiness()的虛擬函數,用於更新其幸福屬性。 每個人都喜歡他們自己的東西。用更多參數覆蓋虛擬功能

喜歡雨的人喜歡聽雨的聲音,並且增加了他們的快樂程度。他們繼承了幸福的人類。

因此,他們需要知道什麼時候正在下雨,同時通過使用updateHappiness(bool isRaining)重載updateHappiness()函數來更新他們的快樂,因爲在這篇文章中:overload virtual function with different parameters in c++,但是這是一個問題,因爲有很多我們希望通過爲每個人調用相同的功能來更新它們。

我們可以將參數存儲在person類的內部,並像本文中那樣在類構造函數中傳遞它:Override number of parameters of pure virtual functions然而,rain不是一個常量狀態,我們不得不調用函數updateRainState(bool isRaining)導致與以前一樣的問題。

我們可以將參數bool isRaining傳遞給每個人,即使他們不關心雨水但它也會是一個問題,因爲有些人喜歡下雨,有些人喜歡看日光,有些人喜歡看它時他們的朋友很高興...所以它會添加許多無用的參數,這似乎是一種浪費。

最後,我能想到的最好的解決方案是在天氣類中有一個靜態函數來獲取雨狀態而不將它作爲參數傳遞,但它看起來像一個全局變量,有些人說它是真的壞!

你會怎麼做才能解決這個問題?

這裏是什麼類是像一個示例代碼:

class HappyPerson 
{ 
public: 
    HappyPerson(): m_happinness(0) {} 
    virtual void updateHappinness() { m_happinness++; } 

protected: 
    int m_happinness; 
}; 

class Weather 
{ 
public: 
    static int isRaining() { return raining; } 

private: 
    static bool raining; 
}; 

bool Weather::raining(0); 

class RainLover : public HappyPerson 
{ 
public: 
    RainLover() : HappyPerson() {} 
    void updateHappinness() { m_happinness++; if (Weather::isRaining()) m_happinness++; } 
}; 

int main() 
{ 
    std::vector<HappyPerson*> happyPeople; 
    happyPeople.push_back(new RainLover); 

    // ... add many other persons 

    std::vector<HappyPerson*>::iterator it; 
    for (it = happyPeople.begin(); it != happyPeople.end(); it++) 
    { 
     (*it)->updateHappinness(); 
    } 
} 
+0

有一件事是肯定的,那些人並不樂意作爲原始指針存儲在容器中。改爲使用'std :: vector >'。 – ArchbishopOfBanterbury

+0

在您的應用程序中,每個「HappyPerson」是否有意識到天氣都是有意義的?對天氣感興趣的人可以在天氣通知發生變化時註冊接收警報,以便他們可以查詢他們感興趣的天氣的各個方面...... –

+0

這僅僅是一個例子,他們仍然樂意不用擔心。我不得不使用一些指針來使多態性生效 – MaxV37

回答

2

你應該考慮一個完全不同的方法 - 使用事件回調來代替。

當某些事情發生特別的變化時,只有感興趣的人受到影響,所以您不應該浪費時間和效果試圖將變更傳遞給其他人。

如果一個人的幸福取決於天氣,那麼讓該人員註冊天氣變化事件。 如果一個人的幸福取決於另一個人的幸福,那麼讓該人登記另一個人的幸福改變事件。

依此類推。

例如:

class HappyPerson; 

class HappinessChangeListener 
{ 
public: 
    void happinessChanged(HappyPerson *person, bool isHappier) = 0; 
}; 

class HappyPerson 
{ 
public: 
    HappyPerson(); 
    virtual ~HappyPerson() {} 

    void updateHappiness(int amount); 

    void registerHappinessChangeListener(HappinessChangeListener *listener); 
    void unregisterHappinessChangeListener(HappinessChangeListener *listener); 
); 

protected: 
    int m_happinness; 
    std::vector<HappinessChangeListener*> happinessChangeListeners; 

    void happinessChanged(bool isHappier); 
}; 

... 

HappyPerson::HappyPerson() 
    : m_happinness(0) 
{ 
} 

void HappyPerson::updateHappiness(int amount) 
{ 
    if (amount != 0) 
    { 
     m_happinness += amount; 
     happinessChanged(amount > 0); 
    } 
} 

void HappyPerson::registerHappinessChangeListener(HappinessChangeListener *listener) 
{ 
    happinessChangeListeners.push_back(listener); 
} 

void HappyPerson::unregisterHappinessChangeListener(HappinessChangeListener *listener) 
{ 
    std::vector<HappinessChangeListener*>::iterator i = std::find(happinessChangeListeners.begin(), happinessChangeListeners.end(), listener); 
    if (i != happinessChangeListeners.end()) 
     happinessChangeListeners.erase(i); 
} 

void HappyPerson::happinessChanged(bool isHappier) 
{ 
    for(std::vector<HappinessChangeListener*>::iterator i = happinessChangeListeners.begin(); i != happinessChangeListeners.end(); ++i) 
     i->happinessChanged(this, isHappier); 
} 

class Weather; 

class WeatherChangeListener 
{ 
public: 
    void weatherChanged(Weather *weather) = 0; 
}; 

class Weather 
{ 
public: 
    Weather(); 

    void rainStarted(); 
    void rainStopped(); 
    bool isRaining(); 

    void registerWeatherChangeListener(WeatherChangeListener *listener); 
    void unregisterWeatherChangeListener(WeatherChangeListener *listener); 

protected: 
    bool m_raining; 
    std::vector<WeatherChangeListener*> weatherChangeListeners; 

    void weatherChanged(); 
}; 

... 

Weather::Weather() 
    : m_raining(false) 
{ 
} 

void Weather::rainStarted() 
{ 
    if (!m_rRaining) 
    { 
     m_rRaining = true; 
     weatherChanged(); 
    } 
} 

void Weather::rainStopped() 
{ 
    if (m_rRaining) 
    { 
     m_rRaining = false; 
     weatherChanged(); 
    } 
} 

bool Weather::isRaining() 
{ 
    return m_raining; 
} 

void Weather::registerWeatherChangeListener(WeatherChangeListener *listener) 
{ 
    weatherChangeListeners.push_back(listener); 
} 

void Weather::unregisterWeatherChangeListener(WeatherChangeListener *listener) 
{ 
    std::vector<WeatherChangeListener*>::iterator i = std::find(weatherChangeListeners.begin(), weatherChangeListeners.end(), listener); 
    if (i != weatherChangeListeners.end()) 
     weatherChangeListeners.erase(i); 
} 

void Weather::weatherChanged() 
{ 
    for(std::vector<WeatherChangeListener*>::iterator i = weatherChangeListeners.begin(); i != weatherChangeListeners.end(); ++i) 
     i->weatherChanged(this); 
} 

class RainLover : public HappyPerson, public WeatherChangeListener 
{ 
public: 
    RainLover(std::shared_ptr<Weather> &weather); 
    ~RainLover(); 

    void weatherChanged(Weather *weather); 

protected: 
    std::shared_ptr<Weather> m_weather; 
}; 

... 

RainLover::RainLover(std::shared_ptr<Weather> &weather) 
    : HappyPerson(), m_weather(weather) 
{ 
    m_weather->registerWeatherChangeListener(this); 
} 

RainLover::~RainLover() 
{ 
    m_weather->unregisterWeatherChangeListener(this); 
} 

void RainLover::weatherChanged(Weather *weather) 
{ 
    updateHappiness(weather->isRaining() ? 1 : -1); 
} 

class HappyLover : public HappyPerson, public HappinessChangeListener 
{ 
public: 
    HappyLover(std::shared_ptr<HappyPerson> &person); 
    ~HappyLover(); 

    void happinessChanged(HappyPerson *person, bool isHappier); 

protected: 
    std::shared_ptr<HappyPerson> m_person; 
}; 

... 

HappyLover::HappyLover(std::shared_ptr<HappyPerson> &person) 
    : HappyPerson(), m_person(person) 
{ 
    m_person->registerHappinessChangeListener(this); 
} 

HappyLover::~HappyLover() 
{ 
    m_person->unregisterHappinessChangeListener(this); 
} 

void HappyLover::happinessChanged(HappyPerson *person, bool isHappier) 
{ 
    updateHappiness(isHappier ? 1 : -1); 
} 

int main() 
{ 
    std::shared_ptr<Weather> weather(new Weather); 
    std::vector<std::shared_ptr<HappyPerson>> happyPeople; 

    happyPeople.push_back(std::shared_ptr<HappyPerson>(new RainLover(weather))); 
    // or: happyPeople.push_back(std::make_shared<RainLover>(weather)); 

    happyPeople.push_back(std::shared_ptr<HappyPerson>(new HappyLover(happyPeople[0]))); 
    // or: happyPeople.push_back(std::make_shared_ptr<HappyLover>(happyPeople[0])); 

    // ... add many other persons 

    weather->rainStarted(); 
    ... 
    weather->rainStopped(); 

    ... 
} 
+0

謝謝,這真的很有幫助 – MaxV37