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?
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.
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?
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 ?
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.
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).
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.
To jak ? Nie chce sobie po prostu wyrobićzłego nawyku. Może powinno się takie rzeczy inaczej rozwiązywać.
Łatwiej by było gdybyś zrobił „jakoś” - tak żeby działało, pokazał, to doradzimy co zmienić a co zostawić.
Okej, postaram się to zaraz zrobić i podesłać
//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.
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.
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.
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
.