Pracuję nad projektem C ++, w którym mam kilka funkcji matematycznych, które początkowo napisałem, aby używać jako część klasy. Jednak kiedy pisałem więcej kodu, zdałem sobie sprawę, że wszędzie potrzebuję tych funkcji matematycznych.
Gdzie najlepiej je umieścić? Powiedzmy, że mam to:
class A{
public:
int math_function1(int);
...
}
A kiedy piszę inną klasę, nie mogę (lub przynajmniej nie wiem, jak to zrobić) używać tego math_function1
w tej innej klasie. Ponadto zdałem sobie sprawę, że niektóre z tych funkcji nie są tak naprawdę powiązane z klasą A. Wydawało się, że były na początku, ale teraz widzę, jak są to po prostu funkcje matematyczne.
Jaka jest dobra praktyka w tej sytuacji? W tej chwili wklejam je na nowe klasy, co jest na pewno najgorszą praktyką.
static
słowo kluczowe?Odpowiedzi:
C ++ może dobrze działać z funkcjami nie-metodycznymi, jeśli nie należą do klasy, nie umieszczaj ich w klasie, po prostu umieść je w globalnym lub innym zakresie przestrzeni nazw
źródło
math_function1(42)
może wywoływać członka bieżącej klasy;special_math_functions::math_function1(42)
wyraźnie wywołuje niezależną funkcję). To powiedziawszy,::math_function(42)
zapewnia taką samą jednoznaczność.// optional
. Dopraw do smaku.Zależy od tego, jak projekt jest zorganizowany i jakiego rodzaju wzorców projektowych używasz, zakładając, że jest to kod ściśle użyteczny, masz następujące opcje:
Zauważ, że pierwsza opcja będzie najlepszym wyborem, a kolejne trzy mają ograniczoną przydatność. To powiedziawszy, możesz jednak spotkać się z tym, że programiści C # lub Java wykonują pewne prace w C ++ lub jeśli kiedykolwiek pracujesz nad kodem C # lub Java, w których użycie klas jest obowiązkowe.
źródło
Jak już wspomniano, wklejanie i kopiowanie kodu jest najgorszą formą ponownego użycia kodu. Jeśli masz funkcje, które nie należą do żadnej z twoich klas lub mogą być używane w kilku scenariuszach, najlepszym miejscem do ich umieszczenia byłaby klasa pomocnicza lub użyteczna. Jeśli nie używają żadnych danych instancji, można je ustawić na statyczne, więc nie trzeba tworzyć instancji klasy narzędzi, aby z nich korzystać.
Zobacz tutaj do dyskusji statycznych funkcji składowych w natywnym C ++ i tutaj dla klas statycznych w zarządzanym C ++. Następnie możesz użyć tej klasy narzędzi, gdziekolwiek wkleisz kod.
Na przykład w .NET rzeczy takie jak
Min()
iMax()
są dostarczane jako elementy statyczne wSystem.Math
klasie .Jeśli wszystkie funkcje są związane z matematyki, i byś otherwiese mieć gigantyczną
Math
klasę, możesz rozbicie go dalej i mieć zajęcia, takie jakTrigonometryUtilities
,EucledianGeometryUtilities
i tak dalej.Inną opcją byłoby umieszczenie funkcji współdzielonej w klasie bazowej klas wymagających tej funkcjonalności. Działa to dobrze, gdy funkcje w pytaniach muszą działać na danych instancji, jednak to podejście jest również mniej elastyczne, jeśli chcesz uniknąć wielokrotnego dziedziczenia i trzymać się tylko jednej klasy podstawowej, ponieważ „wykorzystasz” swoją jedną bazę klasa, aby uzyskać dostęp do niektórych wspólnych funkcji.
źródło
Ujednoznacznij pojęcie „funkcja pomocnicza”. Jedna z definicji to funkcja wygody, z której cały czas korzystasz tylko po to, aby wykonać jakąś pracę. Mogą one mieszkać w głównej przestrzeni nazw i mieć własne nagłówki itp. Druga definicja funkcji pomocniczej jest funkcją użyteczną dla pojedynczej klasy lub rodziny klas.
Teraz
isPrinter
jest dostępny dla każdego kodu, w tym jego nagłówka, aleprint_alignment_page
wymagausing namespace printer_utils::Xerox;
dyrektywy. Można go również określić jakożeby być bardziej zrozumiałym.
C ++ STL ma
std::
przestrzeń nazw, która obejmuje prawie wszystkie swoje klasy i funkcje, ale dzieli je kategorycznie na ponad 17 różnych nagłówków, aby umożliwić koderowi usunięcie nazw klas, nazw funkcji itp., Jeśli chcą pisać ich własny.W rzeczywistości NIE zaleca się używania
using namespace std;
w pliku nagłówkowym lub, jak to często bywa, jako pierwszej linii w środkumain()
.std::
składa się z 5 liter i często wydaje się uciążliwym wstępem do funkcji, której chce się używać (zwłaszczastd::cout
istd::endl
!), ale służy to celowi.Nowy C ++ 11 ma pewne podprzestrzenie nazw dla usług specjalnych, takich jak
które można przynieść do użytku.
Przydatną techniką jest kompozycja przestrzeni nazw . Jeden definiuje niestandardową przestrzeń nazw do przechowywania przestrzeni nazw potrzebnych dla konkretnego
.cpp
pliku i używania jej zamiast zestawuusing
instrukcji dla każdej rzeczy w przestrzeni nazw, której możesz potrzebować.Ta technika ogranicza ekspozycję na całość
std:: namespace
( jest duża! ) I pozwala napisać czystszy kod dla najczęstszych linii kodu, które ludzie piszą najczęściej.źródło
Możesz umieścić go w funkcji szablonu, aby udostępnić go dla różnych typów liczb całkowitych i / lub liczb zmiennoprzecinkowych:
Można również tworzyć zgrabne typy niestandardowe, które reprezentują na przykład liczby ogromne lub liczby zespolone, przeciążając odpowiednie operatory dla typu niestandardowego, aby uczynić je przyjaznymi szablonom.
źródło