Witam,
załóżmy, że mam 2 klasy: Class1 i Class2 i chciałbym np porównywać pewne wartości między nimi np. if( one.getPosition().x < two.getPosition().x). Nie chciałbym, by odbywało się to w mainie, bo przy większych problemach zajmowałoby to dużo miejsca. Czy w "dobrym smaku" jest utworzenie kolejneo pliku (.cpp i.h) zawierające Class1.h i Class2.h w którym bym tylko napisał funkcje porónujące i ją potem załączył do maina? Albo jakaś alternatywa jak powinno to zachodzić, bo mam tak na prawde 3 klasy i muszę pod koniec sprawdzać czy nie kolidują ze sobą (wszystkie 3) i sprawdzać jak daleko są od siebie( tylko 2 ), a problematyczne jest załatwienie tego w tych klasach. Jakieś rady ? Dotychczas słyszałem raczej o podziale na pliki nagłówkowe i źródłowe przy klasach, ale czy tak samo to można robić tylko z np porównywaniem atrybutów kilku klas i nie będzie to błędne?
Podział kodu na mniejsze pliki
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
- Rejestracja: dni
- Ostatnio: dni
Zacznijmy od tego, że klasy nie powinny nazywać się Class1 i Class2, ale załóżmy na potrzeby tego posta, że są to nazwy przykładowe.
Powinieneś w tej chwili mieć:
- class1.h
- class1.cpp
- class2.h
- class2.cpp
- class3.h
- class3.cpp
- main.cpp
Jeśli piszesz program obiektowo, praktycznie wszystkie pliki (z wyjątkiem maina) powinny być parami .h i .cpp, po jednej klasie w każdej takiej parze, a w samym mainie powinno być jak najmniej kodu.
Powinieneś zatem mieć klasę lub klasy które robią w tej chwili większość tego, co masz w mainie.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
Alky napisał(a):
bo mam tak na prawde 3 klasy i muszę pod koniec sprawdzać czy nie kolidują ze sobą (wszystkie 3) i sprawdzać jak daleko są od siebie( tylko 2 )
Co to znaczy, że klasy kolidują ze sobą oraz jak daleko są od siebie?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
Nazwy klas są oczywiście inne ale zapisałem tylko przykładowo. Naturalnie są parami i wszystko się dzieje w nich, tylko pod koniec ( są to samochodziki) chcę sprawdzać czy objekt klasy CarRed nie koliduje, a więc czy nie zderza się z obkiektem CarBlue(red.getGlobalBounds().intersects(blue.getGlobalBounds)) i tutaj chciałem to zamknąć wstępnie w klasie CarBlue używając extern CarRed red; (error) a, że objekt blue kontrolowany jest przez prote AI to musze też sprawdzać i porónywać pozycje objektów red i blue, znajdujących się w innych klasach. No i potrzebuje dostępu do obu klas. Obie dzedziczą z jednej klasy Car więc nie chce np do CarBlue includować CarRed żeby nie było jakichś problemó bo mają niektóre metody i zmienne o tych samych nazwach. I stąd moje pytanie, czy dobrym pomysłem jest załątwienie tego i innym pliku zawierającym obie klasy i wykonującym tylko funkcje ? Nawet jeśli zapropomujecie jakieś inne rozwiązanie to tak na przyszłość, jest to jakiś pomysł, żeby stworzyć plik .h i .cpp bez żadnych definicji klas, tylko zawierającym nagłówki i definicje funkcji ?
- Rejestracja: dni
- Ostatnio: dni
Czy CarRed i CarBlue czymkolwiek się różnią, poza nazwą i kolorem, cokolwiek to oznacza?
Bo może wystarczy ci jedna klasa. A jeśli się różnią, to pewnie przyda się dziedziczenie.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
Różnią się. Obie klasy dziedziczą z Car. Niektóre metdy nazywająsie tak samo, ale działąją inaczej, co rozwiązałem polimorfizemem ( w Car jest czysta metoda wirtualna).
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
Ale nie odpowiedziałeś mi na pytanie. Jest to dobry sposób na takie porównanie "rzeczy" z 2 klas? Mówię tu o tym pliku który będzie includował te obie kalsy i porównywał konkretne rzeczy, a gotową funkcje bym wrzucił do maina.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
To jak ? Nie chce sobie po prostu wyrobićzłego nawyku. Może powinno się takie rzeczy inaczej rozwiązywać.
- Rejestracja: dni
- Ostatnio: dni
Łatwiej by było gdybyś zrobił „jakoś” - tak żeby działało, pokazał, to doradzimy co zmienić a co zostawić.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 32
//Helper.h
#pragma once
#include "CRed.h"
#include "CBlue.h"
#include "Map.h"
void blueSide(CRed red, CBlue &blue);
void isIntersecting(CBlue &blue, CBlue &secound_blue);
void isIntersectingRed(CRed &red, CBlue &blue);
//Helper.cpp
#include "Helper.h"
void blueSide(CRed red, CBlue &blue)
{
if (red.getPosition().x < blue.getPosition().x && red.getPosition().y < blue.getPosition().y) blue.choise = CBlue::NW;
else if (red.getPosition().x < blue.getPosition().x && red.getPosition().y > blue.getPosition().y) blue.choise = CBlue::SW;
else if (red.getPosition().x > blue.getPosition().x && red.getPosition().y < blue.getPosition().y) blue.choise = CBlue::NE;
else if (red.getPosition().x > blue.getPosition().x && red.getPosition().y > blue.getPosition().y) blue.choise = CBlue::SE;
else if (red.getPosition().x < blue.getPosition().x) blue.choise = CBlue::W;
else if (red.getPosition().x > blue.getPosition().x) blue.choise = CBlue::E;
else if (red.getPosition().y < blue.getPosition().y) blue.choise = CBlue::N;
else if (red.getPosition().y > blue.getPosition().y) blue.choise = CBlue::S;
}
void isIntersecting(CBlue &blue, CBlue &secound_blue)
{
if (blue.getGlobalBounds().intersects(secound_blue.getGlobalBounds()))
{
blue.colliding = true;
secound_blue.colliding = true;
}
}
void isIntersectingRed(CRed &red, CBlue &blue)
{
if (red.getGlobalBounds().intersects(blue.getGlobalBounds()))
{
red.colliding = true;
blue.colliding = true;
}
}
Tak wygląda ten nowy plik.
Mniejsza już o to co jest w CRed i CBlue.
I w mainie używam tu zdefiniowanych funkcji.
No i ponawiam pytanie. Czy to dobry sposób na porónywanie wartości z dwóch klas, czy da się takie rzeczy rozwiązywać w jednej klasie urzywając dyrektywy extern czy coś. Pytam czy to dobrze że takądrogęobrałem, czy żeby unikać takich rzeczy i wszsytko załatwiać w klasach jakośprzekazując obiekty innych klas, bo tu mi to sprawiło problem.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
Ogólnie to taki helper wygląda ok. Pytanie tylko dlaczego używasz CarRed oraz CarBlue skoro posługujesz się metodami które są wspólne dla obu klas. Nie wiem co dokładnie masz w klasie CCar, ale takie metody jak getPosition oraz getGlobalBounds powinny się znajdować w CCar, więc zamiast używać kolorowych samochodów możesz do tych metod przekazać CCar i wtedy będzie można je uczynić składowymi CCar Moim zdaniem coś jest nie tak skoro musisz tak rozgraniczać samochody. Ładnie tu pasuje polimorfizm i operowanie na klasie ogólnej.
- Rejestracja: dni
- Ostatnio: dni
Zamień ten helper na klasę (i wymyśl nazwę, nie "helper"), która będzie miała pola redCar i blueCar. Metoda isIntersecting operowałaby na polach tej klasy.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1340
Alky napisał(a):
void isIntersecting(CBlue &blue, CBlue &secound_blue) { if (blue.getGlobalBounds().intersects(secound_blue.getGlobalBounds())) { blue.colliding = true; secound_blue.colliding = true; } } void isIntersectingRed(CRed &red, CBlue &blue) { if (red.getGlobalBounds().intersects(blue.getGlobalBounds())) { red.colliding = true; blue.colliding = true; } }
Te funkcje są identyczne. Nie możesz zdefiniować jednej funkcji w klasie nadrzędnej, np:
bool Car::isIntersecting( Car* other )
{
if ( this->getGlobalBounds().intersects( other->getGlobalBounds() ) ) {
this->colliding = true;
other->colliding = true;
return true;
}
return false;
}
PS. Logika podpowiada, że jeśli funkcja nazywa się isCostam to powinna coś zwracać, chociażby bool.