W wolnym czasie opracowuję emulator NES. Używam C ++, ponieważ jest to język, którego najczęściej używam, znam głównie i lubię najbardziej.
Ale teraz, kiedy poczyniłem pewne postępy w projekcie, zdaję sobie sprawę, że nie używam prawie żadnych konkretnych funkcji C ++ i mogłem to zrobić w zwykłym C i uzyskać ten sam rezultat. Nie używam szablonów, przeciążania operatora, polimorfizmu, dziedziczenia. Co byś powiedział? powinienem pozostać w C ++, czy przepisać go w C?
Nie zrobię tego, aby zwiększyć wydajność, może to być efektem ubocznym, ale chodzi o to, dlaczego powinienem używać C ++, jeśli go nie potrzebuję?
Jedyne cechy C ++, których używam, to klasy do enkapsulacji danych i metod, ale można to również zrobić za pomocą struktur i funkcji, używam nowych i usuń, ale równie dobrze mogę używać malloc i za darmo, i jestem używanie dziedziczenia tylko dla wywołań zwrotnych, które można osiągnąć za pomocą wskaźników do funkcji.
Pamiętaj, że to projekt hobbystyczny, nie mam żadnych terminów, więc czas i praca, które wymagałyby ponownego napisania, nie stanowią problemu, mogą być również zabawne. Pytanie brzmi C czy C ++?
I use C++ because is the language I use mostly, know mostly and like mostly.
I to jest odpowiedź na twoje pytanie. Powinieneś przełączać języki tylko w połowie projektu, gdy występuje problem, którego twój obecny język nie może rozwiązać.I don't use templates, operator overloading, polymorphism, inheritance.
O wiele cenniej byłoby uczyć się i używać pojęć, niż przejść do C. Ponieważ jest to projekt hobby, dlaczego nie skorzystać z kilku rzeczy, których wcześniej nie używałeś? Zawsze możesz rozpocząć inny projekt w języku C i nauczyć się języka, ale w przypadku bieżącego projektu nie ma sensu się przełączać.std::shared_ptr
,std::unique_ptr
,boost::scoped_ptr
,std::vector
,std::deque
,std::map
, itd. Dla funkcji zwrotnych, spójrz do wykorzystania funktorów, aw C ++ 11, ty może również zacząć korzystać z funkcji takich jak funkcje lambda.Odpowiedzi:
Nie jest używany obecnie, ale następnym razem, gdy wyciek pamięci lub uzyskać podwójne kasowania, będziesz błagać, aby wrócić do
std::vector<T>
,std::unique_ptr<T, Del>
istd::shared_ptr<T>
, który może rozwiązać te problemy easily- prawie trywialnie. Tak dzieje się w końcu z każdym, kto używa C w C ++, a mądrzejsi po prostu nie czekają na pojawienie się błędów przed przejściem.Kod, który używa
new
idelete
bezpośrednio tak naprawdę nie należy do C ++, należy do tego rodzaju domku, który nazywamy „C z klasami”. To miejsce, gdzie język był około roku 1985. To nie jest szczególnie podobny do C ++, około roku 2011. Według wszelkiego prawdopodobieństwa, gdzie nauczyłeś się C ++ po prostu nie uczą go bardzo dobrze, że coś jest niestety dość common- iz lepszą edukację, to będzie znajdź zastosowanie tych funkcji.W szczególności, jak wymieniłem powyżej, ogólne struktury danych C ++ i klasy zarządzania zasobami po prostu znacznie przewyższają wszystko, co C ma do zaoferowania. Jeśli chcesz dynamicznie alokowanej tablicy, użyj
std::vector<T>
. To dość powszechny przypadek użycia. Jeśli ich nie używasz, istnieje duże ryzyko niepotrzebnego błędu w kodzie - szczególnie związanego z zarządzaniem zasobami. C ++ może zagwarantować bezpieczeństwo i ponowne użycie kodu w sposób, którego C nigdy nie będzie w stanie dotknąć.Myślę jednak, że i Ty możesz oczekiwać zbyt wiele. Pisanie szablonów i przeciążanie operatorów nie jest powszechne wśród konsumentów bibliotek. Jeśli używasz kodu
std::vector<T>
, nie musisz pisać szablonu, aby tak się stało. Jeśli używasz kodustd::string
, nikt nie zmusza cię do przeciążenia operatorów. Musisz tylko robić te rzeczy, aby pisaćstd::vector<T>
istd::string
- ale nadal możesz z nich w pełni korzystać.Polimorfizm / dziedziczenie ma również tylko określony przypadek użycia. Jeśli twój kod nie wymaga od ciebie pisania szablonów ani korzystania z funkcji wirtualnych, to tak nie jest, a istnieją programy lub segmenty programów, w których nie musisz pisać własnych szablonów.
Ponadto nie ma wzrostu wydajności w C w porównaniu z C ++.
źródło
make_shared
istnieje i możesz napisać prostymake_unique
szablon, który wykonuje tę samą pracę. To jest bezpieczniejsze.make_shared
jest bardziej wydajny. Tylko funkcje fabryczne mogą gwarantować wyjątkowe bezpieczeństwo.Nawet jeśli nie używasz funkcji specyficznych dla C ++, kompilator C ++ będzie wychwytywał więcej problemów niż C ze względu na bardziej rygorystyczny system C ++.
źródło
Spojrzałbym na to z drugiej strony. Czy coś zyskasz przepisując kod w C? Nawet w przypadku projektu czysto hobbystycznego koszty takiego przepisywania są powiązane. Jeśli nic innego, jak przypuszczam, nie byłoby tak zwane kosztem alternatywnym - tj. Innymi rzeczami, które mogłeś zrobić w tym czasie, gdybyś nie
marnował czasu naprzepisywanie go w C.Konkluzja: jeśli nie sądzisz, że kod prawdopodobnie zostanie użyty w środowisku, w którym dostęp do C ++ jest naprawdę ograniczony (lub nie istnieje), byłoby to w najlepszym wypadku bezcelowe marnowanie czasu. Przynajmniej z mojego doświadczenia wynika, że zwykle znacznie wykracza poza to bardzo szybko - myśląc o kodzie, który napisałem w C ++, który musiałem przekonwertować na C, całkiem dobrze pamiętam, że nawet w kilku przypadkach wydawało się, że powinno być trywialne, używałem o wiele więcej funkcji specyficznych dla C ++, niż początkowo sobie wyobrażałem. Aby mieć dużą nadzieję, że w ogóle się przydadzą, musiałbyś raczej celować w C89 / 90, w którym to przypadku szybko przypominasz sobie takie rzeczy, jak konieczność zdefiniowania wszystkich zmiennych na początku bloku zamiast tego, gdzie faktycznie są używany.
Krótko mówiąc, chyba że jesteś pewien, że przepisanie w C przyniesie realne korzyści, prawie nieuchronnie jest o wiele lepsze rzeczy do zrobienia.
źródło
Jako ogólniejsza odpowiedź:
Nie przełączaj się na C ++ tylko dlatego, że używasz niektórych z jego bardziej unikalnych funkcji. Pewnego dnia możesz potrzebować tych funkcji i po prostu uderzysz się w głowę, ponieważ używasz C.
źródło
W przypadku rozwoju hobbystów rozważałbym powrót do zwykłych języków C. C i języki podobne do C są częściej obsługiwane w małych modułach do programowania hobby.
Wiele odpowiedzi tutaj może pochodzić z profesjonalnych typów oprogramowania. Jako hobbysta nie będziesz kodować w sposób ciągły ani pełny. Zastanów się więc, w którym języku prawdopodobnie zapamiętasz lub zapomnisz o dziwactwach, jeśli odłożysz projekt na rok, a potem wrócisz i spróbujesz przeczytać kod po tym, jak zaczniesz pisać. C ++, mając bogatszy zestaw funkcji, może wymagać więcej lub mniej czasu, aby ponownie uzyskać, w zależności od stylu kodowania.
źródło
Odpowiedź na pytania nie jest łatwa, ponieważ nie wiemy, czy pracujesz nad projektem, aby poprawić swoje umiejętności językowe (C vs C ++) lub poprawić inne umiejętności programowania (projektowanie, rozwiązywanie problemów itp.).
„Jedyne cechy C ++, których używam, to klasy do enkapsulacji danych i metod, ale można to również zrobić za pomocą struktur i funkcji”. To nie jest prawda.
structs
w C nie obsługują enkapsulacji i nie mogą zawierać funkcji (metod) - przynajmniej nie bez użycia technik takich jak wskaźniki do funkcji. Ponadto funkcje w C są słabsze, ponieważ nie mogą być przeciążone.„Używam new i delete, ale równie dobrze mogę używać malloc i free, i używam dziedziczenia tylko do wywołań zwrotnych, które można uzyskać za pomocą wskaźników do funkcji.” Jak deadmg wspomniano, używając bezpośrednio
new
idelete
w C ++ nie jest wskazany. Ponadto dziedziczenie IMHO (i GoF) w OOP powinno być preferowane nad kompozycją tylko wtedy, gdy wymagany jest polimorfizm. I nie sądzę, aby osiąganie polimorfizmu (późne wiązanie) w C przy użyciu wskaźników do funkcji było banalne.Poza tym nie będę cię przekonywał, że C ++ jest „lepszy” niż C, ponieważ jest to kwestia preferencji i zawsze zależy od problemu, który próbujesz rozwiązać (użycie funkcji OOP do opracowania emulatora NES może być dobry pomysł).
źródło
structs
w C można w rzeczywistości wykorzystać do enkapsulacji metod. Po prostu tworzysz strukturę wskaźników funkcji i inicjujesz je, aby wskazywały dowolne funkcje. Na przykład spójrz na lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 .printf
), ale robiąc to, tracisz sprawdzanie dowolnego typu. Nie ma sposobu, aby mieć skończony zestaw akceptowalnych deklaracji: jest to 1 (i dostajesz sprawdzanie typu) lub „wiele” (i tracisz wszystkie sprawdzanie typu, na wielkie ryzyko osobiste). Jak w większości rzeczy w C, jest to możliwe, ale często niewygodne.Jestem bardzo początkujący, więc oto moje 2 bity.
Uczę się C i C ++ na Wibit.net z kilkoma ładnymi podstawowymi samouczkami wideo, być może mogą ci bardzo pomóc w omówieniu „sytuacji” (nie reklamy!)
Radzę zmienić się na C, aby się uczyć, ponieważ jesteś hobbystą, będzie to przyjemność, a nie problem.
Radzę więcej. Zrób to w obu językach. Porównaj sposób i rozwiązania, które znajdziesz i wykorzystasz. Jestem pewien, że nie będzie tak łatwo, jak się spodziewasz ... ale na pewno wiele się nauczysz!
źródło
Oto zalety i wady C ++ vs. C:
źródło