często pakować jakieś dane do class
aby uniknąć błędów z publicznym dostępem do Globalnej/i dostarczyć pewne wspólne sposoby na to, np:"onEachSubelement (...)" metoda C++
class GameArea{
std::vector<Enemy*> enemies;
std::wstring name;
public:
void makeAllEnemiesScared();
Enemy * getEnemy(unsigned index);
};
GameArea
jest tylko uproszczony przykład tutaj. Byłby to rodzaj niestandardowego kontenera/menager z pewnymi specjalistycznymi metodami (ale to nie tylko kontener).
Idealną sytuacją jest, gdy wiem, jakie operacje będą wykonywane na każdym Enemy
naraz i występują one w kilku miejscach, więc mogę zadeklarować je w GameArea
bezpośrednio (jak makeAllEnemiesScared()
).
W innych przypadkach mogę iść z:
for(unsigned i=0; i<gameArea->getEnemiesCount(); i++){
Enemy * enemy = gameArea->getEnemy(i);
...
}
Ale cierpi z niektórych wad:
- Nie mogę korzystać z C++ 11 czystego & piękny
for(auto &Enemy : enemies)
pętli - To nie jest wydajne (tyle połączeń do
getEnemy(index)
), - To nie jest przeznaczenie dla
getEnemy(index)
do iterowania rzucania wszystkimi elementami - jest to użyteczne w przypadku, gdy chcemy wybrać pojedyncze lub kilka z nich, ma również sprawdzić dlaindex < enemies.size()
wewnątrz - to jest okropne, aby sprawdzić to na każdym elemencie w pętli.
UWAGA: myślę o przypadkach, gdy robię coś wyjątkowego (nie warto stworzyć metodę oddzielony w GameArea
, ale na każdym elemencie z GameArea::enemies
).
Myślałem o pewnej metodzie GameArea::onEachEnemy(... function ...)
, która ma function
(a może lepiej lambda?) Jako parametr. Czy to dobre rozwiązanie?
A może należy zastosować inne podejście? Podobnie jak zwrot std::vector
z GameArea
- który wygląda dla mnie trochę "brzydko". Nie chcę, aby użytkownik myślał, że może bezpośrednio dodawać lub usuwać elementy do/z tego numeru.
Twoja sugestia "onEachEnemy" brzmi dla mnie dobrze. – molbdnilo
Zakładam, że wszystkie 'getEnemy' ma na celu zwrócić' wrogów [i] '? Następnie możesz wbudować funkcję, a kompilator najprawdopodobniej zoptymalizuje wywołanie. Możesz także uniknąć powtarzającego się wywołania 'getEnemiesCount', wywołując je przed pętlą i zapisując wynik. Możesz także zapewnić interfejs iteratora lub, jak się zastanawiasz, utworzyć funkcję "dla każdego". Ale przede wszystkim powinieneś profilować swój program, aby sprawdzić, czy to naprawdę jest oszustwo, o którym myślisz. –
Aha, i pamiętajcie, że wektor 'operator []' nie wykonuje żadnych sprawdzeń granicznych, zakłada, że użytkownik wektora zadba o to, aby nie wyjść poza granice. Jeśli tak bardzo martwisz się nieefektywnością, prawdopodobnie powinieneś zrobić to samo, tj. Zrezygnować z sprawdzania granic z 'getEnemy'. Ale tak jak powiedziałem w poprzednim komentarzu * najpierw * profil i upewnij się, że to naprawdę jest tak nieefektywne, jak ci się wydaje. –