2015-04-29 123 views
0

我正在構建一個組件系統,其中抽象類型Component是從組件繼承而來的。到目前爲止,我有可繪製的,物理的,可移動的和其他組件。一切似乎進展順利,並在Game I類執行以下操作:防止未經授權使用組件

void Game::init() 
{ 
    pPlayer->addComponent(pMovable); 
} 

void Game::processEvents() 
{ 
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) 
     pMovable->moveUp(2.f); 

    // etc.. 

    pPlayer->setVelocity(pMovable->getVelocity()); 
} 

void Game::update() 
{ 
    pPlayer->update(0); 
} 

void Game::play() 
{ 
    while (pWindow->isOpen()) 
    { 
     // ... 
     processEvents(); 
    } 
} 

到目前爲止,該組件系統是很基本的,簡單的。玩家的類型爲Object,每當我打電話給玩家的更新函數時,我也會調用Object的更新函數。這應該是真正的自動化,但這將在未來發生變化。什麼是真正的問題是這樣的:

pPlayer仍然可以訪問pMovable的速度即使它沒有添加pMovable作爲組件。這是有問題的,因爲這意味着任何人都可以簡單地從pMovable獲得速度,然後將其插入到對象中,而不必將pMovable作爲其組件的一部分添加。現在,傾向於發生的事情是,由於沒有可移動的組件來調節它,因此移動變得不受管理。我認爲這是對這個組件的未經授權的使用,我想要開發一種組件可以拒絕將它的功能用於它不屬於的對象的方式。這個問題有很多解決方案,我需要一個高效實用的解決方案。這裏是我的:

  1. 如果客戶端試圖分配一個組件功能到它自己沒有添加它;

  2. 創建一個系統,通過該系統識別對象和組件,並且組件跟蹤它擁有的對象,並且對象跟蹤它擁有的組件。因爲這是一種多對多的關係,所以必須創建一個管理所有這些的中間類;它也避免了一個循環的頭文件。

  3. 有一個函數不是簡單'停用'的對象的一部分。這需要使用像「componentAdded」這樣的布爾值,並且所有函數都必須檢查組件是否被添加,否則該函數將不會做它應該做的事情。

如果您有其他的解決方案,以防止未經授權使用的組件,請分享它們的我渴望向別人學習它們如何實現的/或將實現一個組件系統,因爲我在這裏做。

+3

[MCVE](http://stackoverflow.com/help/mcve)。我個人發現很難理解你對'pMovable'的看法。 – AndyG

+0

我不認爲你的答案是有幫助的。我已經說過'pMovable'是一個組件,並且隱式地是一個可移動的組件。它具有我不希望非所有者對象不具有的功能。 – Poriferous

+3

我同意@AndyG,一個MCVE會有幫助。如果您在代碼中顯示完整的示例*,我們可以更容易理解您的需求。*您可能認爲已經用口頭解釋了足夠的*,但是一個人認爲他們已經溝通和其他人都瞭解。 – Brian

回答

0

你不能阻止特定的類繼承。這是一個全有或全無的命題:任何類都從基礎繼承或沒有。

最好的你可以希望的是縮小界面。例如,您可能想要使用類Stationary_ObjectEnemy_Object來優化接口,而不是允許功能中的Object的後代。這使您可以編寫採用任何Enemy_Object並且不會採用Stationary_Object(如樹或牆)的函數。

編輯1:與朋友
可以通過聲明成員爲私有,並使用friend類授予訪問特定的類允許成員訪問作弊。問題是,只要創建新類型的朋友,就需要修改包含數據的類。我相信這種使用friend的船破壞了可重用性的目的。

編輯2:檢測所有權
比方說,我們有三類:

class Engine; 

class Car 
{ 
    Engine car_engine; 
}; 

class Boat 
{ 
    Engine boat_engine; 
}; 

和一個功能:

void Fix_Car_Engine(Engine& e) 
{ 
} 

有一個在C++中沒有方法爲Fix_Car_Engine知道它正在修理汽車引擎或船引擎。該函數只知道它已經被賦予了一個通用的引擎來解決(或者只知道變量的常見引擎的東西)。

這個問題可以通過優化或縮小的界面得到緩解:

class Car_Engine : public Engine; 
class Boat_Engine : public Engine; 

class Car 
{ 
    Car_Engine diesel_engine; 
}; 

class Boat 
{ 
    Boat_Engine propellor_engine; 
}; 

在上面的例子中,發動機類有兩個專業:Car_EngineBoat_EngineCar現在有一個Car_Engine成員和Boat有一個Boat_Engine

的功能現在可以創建特殊發動機運轉:

void fix_boat_engine(Boat_Engine& be); 
void fix_car_engine(Car_Engine& ce); 

fix_car_engine現在只能用汽車發動機工作原理。你可以說它適用於任何擁有汽車發動機的車型(只要你通過汽車發動機成員)。同樣,fix_boat_engine函數只能在船引擎上運行。

鑑於:

class Rocket_Engine : public Engine; 

此外,這種專業化防止Rocket_Engine被傳遞給任一功能。這些功能需要特定的引擎類型。

+0

我不想阻止特定的類繼承。我只是不希望組件被沒有擁有組件的對象使用。 – Poriferous

+0

如何判斷對象A是否擁有對象B?我可以創建一個包含Engine實例的結構Car。功能如何知道發動機屬於汽車還是船? –

+0

@不擁有組件的多孔對象將無法訪問該組件_unless您將其引用到component_。所以停止給它參考。還是你使用全局變量? (facepalm) – developerbmw