Jestem programistą w C i C ++, chociaż nie trzymam się żadnego z tych języków i nie piszę ich mieszanki. Czasami posiadanie kodu w klasach, być może z przeciążeniem operatora, lub szablonów i och tak świetny STL jest oczywiście lepszym sposobem. Czasami użycie prostego wskaźnika funkcji C jest znacznie bardziej czytelne i wyraźne. Więc znajduję piękno i praktyczność w obu językach. Nie chcę wchodzić w dyskusję na temat: „Jeśli je zmiksujesz i skompilujesz za pomocą kompilatora C ++, to już nie będzie to miks, to wszystko C ++”. Myślę, że wszyscy rozumiemy, co mam na myśli, mieszając je. Nie chcę też rozmawiać o C vs. C ++, to pytanie dotyczy C ++ 11.
C ++ 11 wprowadza, jak sądzę, znaczące zmiany w działaniu C ++, ale wprowadził wiele specjalnych przypadków, wyjątków i nieprawidłowości, które zmieniają zachowanie różnych funkcji w różnych okolicznościach, nakładając ograniczenia na wielokrotne dziedziczenie, identyfikatory działające jak słowa kluczowe, rozszerzenia literałów łańcuchowych, przechwytywania zmiennych funkcji lambda itp.
Wiem, że w pewnym momencie, kiedy powiesz C ++, wszyscy przyjmą C ++ 11. Podobnie jak w dzisiejszych czasach C, najprawdopodobniej masz na myśli C99. To sprawia, że rozważam naukę C ++ 11. W końcu, jeśli chcę kontynuować pisanie kodu w C ++, może w pewnym momencie będę musiał zacząć korzystać z tych funkcji tylko dlatego, że mają to moi koledzy.
Weźmy na przykład C. Po tylu latach wciąż wiele osób uczy się i pisze kod w C. Dlaczego? Ponieważ język jest dobry. Co dobre, to że przestrzega wielu zasad, aby stworzyć dobry język programowania. Więc oprócz tego, że jest potężny (który jest łatwy lub trudny, prawie wszystkie języki programowania), C jest regularny i ma kilka wyjątków, jeśli w ogóle. C ++ 11 jednak nie wydaje mi się. Nie jestem pewien, czy zmiany wprowadzone w C ++ 11 poprawiają język.
Pytanie brzmi: dlaczego miałbym się uczyć C ++ 11?
Odpowiedzi:
Powinieneś się tego nauczyć, jeśli uważasz, że będziesz musiał to wiedzieć w przyszłości, aby znaleźć pracę. Jeśli masz pewność, że nadal będziesz sprzedawać siłę roboczą jako C / C ++ [i cokolwiek innego, co możesz wiedzieć], nie ucz się jej. Jeśli twój szef każe ci używać C ++ 11, powiedz „nie, nie robię tego”. Jeśli cię zwolni, idź do pracy gdzie indziej. Naucz się C ++ 11, gdy przewidujesz, że wkrótce nie będziesz w stanie znaleźć satysfakcjonującego zatrudnienia dzięki umiejętnościom, które obecnie znasz.
Chciałem wyjaśnić moje uzasadnienie: nie jestem anty-C ++ 11. Wystarczy powiedzieć, że możesz uogólnić pytanie OP na „Dlaczego powinienem nauczyć się X”. Nigdy nie nauczyłem się ML, schematu ani haskell, ponieważ mam pracę w C i C ++. Jestem pewien, że te języki są dla kogoś przydatne, ale nie są dla mnie korzystne, aby się uczyć. Jeśli ktoś zaoferuje mi dobre pieniądze na program w ML, mogę spróbować się tego nauczyć.
źródło
To proste. C ++ 11 sprawia, że kod jest znacznie łatwiejszy, czystszy w pisaniu i szybszy.
nullptr
jest ulepszeniem VAST w stosunku do starego0
. Jest bezpieczny dla typu i nie konwertuje, kiedy nie powinien - w przeciwieństwie do0
. To dobra rzecz, którejnullptr
nie da się przekonwertować naint
. To w ogóle nie ma sensu. Czy wiesz, co znalazł Komitet C ++, gdy próbowali rozważyć#define NULL nullptr
? Rzeczy jakchar c = NULL;
. Jak okropne to jest? Jedynym powodem, dla którego istnieje tutaj wyjątek, jest to, żebool
jest uważany za typ integralny, co jest całkiem błędne - ale było to wcześniej w C ++ iw C. Fakt, żenullptr
nie można przekonwertować, jest dobry , jest świetny i powinieneś go pokochać.A może odniesienia do wartości i szablony variadic? Szybszy, bardziej ogólny kod. To całkowita wygrana.
Co powiesz na ulepszenia biblioteki? Takie rzeczy
function
,unique_ptr
ashared_ptr
są o wiele lepsze niż to, co było tam wcześniej, że to niemożliwe, aby twierdzić, że C ++ 03 droga była lepsza.Nawet nie zdalnie równoważny. Makra są złe z sześciu miliardów powodów. Nie zamierzam tutaj przytaczać ich wszystkich, ale dobrze wiadomo, że makr należy unikać praktycznie we wszystkich celach, w których można by ich uniknąć. Co będziesz robić, kiedy to będzie
Och, czekaj, mam nadzieję, że się nie zwiększyłeś
x
. Na którą wersję funkcji szablonu jest całkowicie odporna. Mam również nadzieję, że na przykład nie doceniasz przestrzeni nazw .W funkcjonalnym API, np. Algorytmach STL, odwołanie jest w porządku. Jeśli jest to zapisane połączenie zwrotne, musisz przechwycić według wartości. Każda dokumentacja dotycząca funkcji powinna wyraźnie wskazywać, która jest konieczna. Fakt, że kod jest zapisany w lambdzie, nie ma znaczenia dla problemu odwoływania się do zmiennych lokalnych - jeśli przekażesz zwykły obiekt funkcji, będziesz miał dokładnie taki sam problem. I to nie jest problem. W ogóle. Ponieważ jest to z natury oczywiste, kiedy można i nie można odwoływać się do zmiennych lokalnych.
Wiele osób nie myje zębów rano. Jest wielu morderców, gwałcicieli i prostytutki. I politycy. Ludzie, którzy popełniają samobójstwa. Czy twierdzisz, że dzięki temu te działania są dobre lub przydatne? Oczywiście nie. Logicznym błędem jest to, że tylko dlatego, że ktoś to zrobił, dlatego musi być dobry lub przydatny.
C jest wciąż pisany z trzech powodów: ponieważ C ++ to dziwka do zaimplementowania, na przykład w trybie osadzonym lub w trybie jądra; ponieważ starsze bazy kodu są napisane w C i ich aktualizacja byłaby zbyt kosztowna, chociaż nawet to jest wątpliwe, biorąc pod uwagę doskonałą współpracę C w C ++; a ponieważ ludzie, którzy to piszą, nie wiedzą, jak programować. to jest to! Nie ma innego powodu, aby pisać C.
Co powiesz na żałosne tablice w stylu C, na prosty przykład? Liczba osób, które nie potrafią odczytać tablic i wskaźników prosto w ich głowę, jest nieprzyzwoita. Nie wspominając o tym, że biblioteka C Standard jest niezwykle niebezpieczna.
Wasze podstawowe argumenty pełne są logicznych błędów i nieporozumień.
źródło
C ++ 11 nie jest nowym językiem; jest to tylko rozszerzenie / modyfikacja C ++, którą już znasz. C ++ 11, podobnie jak każdy inny język programowania, składa się z funkcji. Wiele z nich było tam wcześniej, niektóre z nich są nowe. Ale twoje pytanie naprawdę brzmi: czy powinienem nauczyć się wszystkich funkcji języka (w tym przypadku C ++ 11), czy tylko zapoznać się z nim w 90%?
IMO, nawet jeśli nie używasz całego języka, powinieneś przynajmniej przeczytać o tym, co nowe funkcje dla Ciebie robią. Wiele z nich zostało wprowadzonych w celu ułatwienia pisania kodu biblioteki / frameworka (zwłaszcza szablonów) (na przykład zanim C ++ 11 perfekcyjne przekazywanie nie było możliwe), ale jeśli nigdy wcześniej nie było takiej potrzeby, istnieje szansa, że wygrasz nie zauważam, że te funkcje zostały dodane w C ++ 11.
Z drugiej strony, jeśli wcześniej zajmowałeś się pisaniem kodu biblioteki / rdzenia, który naśladuje niektóre funkcje STL / Boost i okazało się, że jesteś ograniczony przez język, ponieważ w 95% masz bardzo fajne, eleganckie rozwiązanie, ale potem zostałeś zatrzymany, ponieważ dowiedziałeś się, że język po prostu nie obsługuje tego, czego chcesz, zdasz sobie sprawę z naprawdę niesamowitej mocy C ++ 11. Odkąd nasz zespół zaktualizował do wersji VS2010 (i odkryliśmy Boost w tym procesie), byłem w stanie wydobyć szalony niesamowity kod, który byłby po prostu niemożliwy przed takimi rzeczami, jak referencje wartości r i przekazywanie parametrów szablonu.
Również rzeczy takie jak lambda mogą wyglądać na obce, ale nie wprowadzają nowego konstruktu. Zamiast tego znacznie ułatwiają pisanie tego, co mieliśmy wcześniej. Poprzednio każda funkcja lambda musiała być osobną klasą. Teraz to tylko {... kod ...}. Kocham to.
Kluczem jest to, aby nie patrzeć na te funkcje i zastanawiać się, jak zniechęcająca jest lista. Zamiast tego używaj C ++ tak, jak zwykle, i kiedy natrafisz na scenariusz, w którym te nowe funkcje C ++ 11 są przydatne (ponad 90% ludzi nigdy nie dojdzie do tego punktu), będziesz bardzo szczęśliwy, że rozszerzenie do języka zostało zrobione. Na razie sugeruję, abyś nauczył się wystarczająco dużo o języku, aby wiedzieć, co tam jest, niekoniecznie jak korzystać z tego wszystkiego.
źródło
Gdy to zrobisz, przewiń w górę lub otwórz nowy plik źródłowy i dodaj tam definicję funkcji. Następnie musisz wrócić i kontynuować pracę nad tym, nad czym pracowałeś, co do pewnego stopnia cię rozprasza.
Poza tym, gdy inni czytają Twój kod, lambda może w niektórych przypadkach być bardziej samodokumentująca, zamiast mówić „Och, co ta funkcja robi?” i skacząc do jego deklaracji, możesz po prostu rzucić okiem na to, co robi na swoim miejscu.
Herb Sutter miło mówi o lambdach, być może może cię lepiej przekonać:
http://channel9.msdn.com/events/PDC/PDC10/FT13
Ponieważ nie możesz tego zrobić, gdy używasz algorytmów STL lub jakiejkolwiek funkcji, której używasz, która wymaga przekazania funkcji.
Nie ma sposobu, aby uzasadnić to użycie zamiast lambdas, nie można wszędzie wypełnić makra. Makra i funkcje mają różne cele, a jeden z nich ogólnie nie zastępuje drugiego.
Zgadzam się, to brzydkie. Pamiętam jednak, jak mówiłem „dlaczego, do diabła, mam wymyślić rodzaj tego wyrażenia, chociaż kompilator może to wywnioskować?” w wielu przypadkach. To może bardzo pomóc w tych chwilach.
Podsumowując:
Mimo że nowe funkcje C ++ 11 wydają się brzydkie pod względem składni, myślę, że można się do nich przyzwyczaić w krótkim czasie. Na początku każdy nowy konstrukt językowy jest trudny do nauczenia; wyobraź sobie, kiedy po raz pierwszy nauczyłeś się pisać całą klasę: umieszczanie deklaracji w pliku nagłówkowym, nie zapominając o dodatkowym średniku na końcu, umieszczanie definicji w pliku źródłowym, w tym pliku nagłówkowym, przy jednoczesnym zapewnieniu, że ma on zabezpieczenie przed zapobieganiem wiele inkluzji, nie zapominając o operatorze rozdzielczości zakresu w deklaracjach funkcji członka i tak dalej ...
Ale jestem pewien, że po napisaniu kilku klas przyzwyczajasz się do tego i nie myślisz o złożoności tego procesu: Ponieważ wiesz, że klasa znacznie ułatwia pracę jako programista, a narzędzie zarobki z tego nowego konstruktu są znacznie większe niż utrata użyteczności w czasie, gdy próbujesz nauczyć się języka . Myślę, że może to być powód, dla którego warto próbować się uczyć lub używać C ++ 11 w podobny sposób.
źródło
bool is_alive;
ibool thisSpecialObjectOfMineIsAlive;
. Obie robią to samo, ale druga wygląda naprawdę brzydko. Czemu? Ponieważ błędnie myślałem, że podanie większej ilości informacji czyni je wyraźniejszym, ale zrobiło się odwrotnie. Jest to ta sama umowa, Stroustrup miał na myśli dobro, dając nam funkcje, ale po prostu nie sprawił, że wyglądał dobrze. Dla mnie to pokazuje zły projekt.W rzeczywistości OP ma pewne punkty, od większości odpowiedzi. Ale są „dalekie” w widzeniu. C ++ (w tym podzbiór C) ma długą historię, w której wiele funkcji było dodawanych przez cały czas, niektóre z nich były używane mniej lub bardziej często - poprzez wykorzystanie teir i błędy - dopracowane w innych i innych.
Czasami zdarza się, że po wprowadzeniu nowej funkcji stara jest już potrzebna lub jest z nią sprzeczna. „Czysty” język powinien być samowystarczalny i nie trzeba już usuwać potrzebnych funkcji.
Ale dodawanie niczego nie niszczy. Usunięcie (lub zmiana) powoduje uszkodzenie istniejącego kodu, który jest nadal w produkcji, więc niezależnie od dodanej funkcji musisz uważać, aby nie złamać istniejącego kodu (w szczególności nie przerywać go po cichu , powodując, że robi on różne rzeczy zgodnie z przeznaczeniem ).
Czy musisz się tego wszystkiego nauczyć? Tak, ponieważ wszystkie funkcje są dobre lub złe, prędzej czy później. Czy jest to dobra rzecz dla „jakości” języka (przyznając, że istnieje obiektywna miara), to inna historia: jak długo należy zachować zgodność wsteczną? trudno znaleźć odpowiedź, gdy ktoś mówi 3 lata, a niektórzy mówią 50.
Alternatywą dla utrzymania bardziej regularnego C ++ jest ... łamanie go częściej, z restartem od zera. Ale nie będzie już C ++.
Są też próby zrobienia tego (na przykład D: na przykład znacznie bardziej ortogonalne, jak w rzeczywistości C ++ (nawet 11)), ale jak popularne są? Jednym z powodów ich trudności w utrzymaniu rozpędu jest niezgodność z wieloma istniejącymi kodami, które wciąż muszą zostać uruchomione.
C ++ 11 jest dla mnie wyraźnie kompromisem między nowymi potrzebami a kompatybilnością wsteczną. Doprowadziło to do pewnego „bałaganu” specyfikacji i implementacji. Dopóki koszt tego „bałaganu” nie będzie niższy niż koszt niezgodności ... musisz wyjść z tym kompromisem.
Jeśli nie możesz tego dłużej tolerować, lepiej rozważyć inny młodszy język. C ++ po prostu nie można uprościć w tym sensie. Nie w tym wieku.
źródło
Nawet jeśli zdecydujesz się zignorować nowe funkcje C ++ 11, nadal będziesz z nich korzystać, ponieważ standardowa biblioteka C ++ z nich skorzysta. Na przykład w C ++ 98 posiadanie zmiennej typu
vector<string>
mogło potencjalnie spowodować awarię wydajności z powodu liczby kopii, które trzeba wykonać, gdy wektor rośnie. W przypadku konstruktora przenoszenia C ++ 11 nie stanowi to problemu. W rzeczywistości chciałbym, aby C ++ 11 przyniósł nam więcej nowych funkcji, nie mniej - szczególnie w Bibliotece standardowej.źródło
Po pierwsze, większość studentów obecnie uczy się Java lub .NET, a nie C. Po drugie, ludzie nadal używają C nie tylko ze względu na jego zalety jako języka, ale głównie dlatego, że istnieje ogromna ilość istniejącego oprogramowania napisanego w C, które musi być utrzymywanym i rozszerzanym, a ponieważ w wielu przypadkach (np. platformy wbudowane) kompilator C jest wszystkim, co istnieje. Nawiasem mówiąc, są to niektóre z powodów, dla których ludzie nadal piszą w języku COBOL.
Bardzo rzadko programiści w branży rozpoczynają pracę nad nowym projektem, który nie jest powiązany z istniejącą bazą kodu, i kontynuują pracę w pojedynkę. Powodem do nauki C ++ 11 jest to, że prawdopodobnie będziesz musiał radzić sobie z kodem napisanym przez innych ludzi, który korzysta z nowych funkcji. Ponadto funkcje, które zostały dodane zostały dodane z jakiegoś powodu. Gdy się ich nauczysz i będziesz z nich korzystać, możesz je docenić.
źródło
good
następnym zdaniu, oznacza to , że przestrzega zasad dobrego projektowania języka programowania. Nie wiem, gdzie studiujesz, ale znam 4 lub 5 krajów i wszyscy zaczynają uczyć się programowania w C. Jak już powiedziałem, w C nie ma żadnych wyjątków (coś, co jest przeciwne w Javie, ledwo można było znajdź konstrukcję, która nie ma wyjątku).Dojdziesz do momentu w swojej karierze w C ++, gdzie powiesz sobie: „Na pewno żałuję, że funktory nie są prostsze” lub „Dlaczego NULL jest int?”. i wtedy zrozumiesz C ++ 11.
źródło
NULL
powinien byćint
. Nie powinno. To, co nie uważam za właściwe, to wprowadzenie konstruktu w języku, który to rozwiązuje, ale wprowadza wyjątki. Powinni byli być w stanie zrobić to samo w lepszy sposób.Uczenie się jest zawsze korzystne. Wiedza to potęga.
Zasadniczo taka jest odpowiedź. Cała reszta to tylko szczegóły tego, jak dokładnie możesz z niego skorzystać i jakie masz moce, wiedząc o tym, a jest ich tak wiele, że każde wyliczenie byłoby niepełne.
Jednym z przykładów jest twoje pytanie. Nie byłbyś w stanie nawet o to zapytać, nie ucząc się choć trochę.
I jak skomentowałem - prawdziwą troską nie jest, dlaczego się uczyć, ale po co korzystać . I to jest zupełnie inne pytanie.
źródło
Powinieneś nauczyć się C ++ 11, ponieważ dodane funkcje pozwalają pisać lepszy kod. Niektóre osoby wspominały o bezpieczeństwie typów wskaźników NULL i lambd, które są bardzo miłe. Chcę jednak zwrócić uwagę na to, co według mnie jest najbardziej dramatyczną zmianą w C ++ 11, szczególnie w dużym środowisku produkcyjnym: semantykę przenoszenia.
C ++ 11 obsługuje osobne pojęcia „przenoszenia” i „kopiowania”. W zwykłym C ++ mamy po prostu operatora =, który w zasadzie robi oba te elementy. Ale tak naprawdę, przedstawiamy dwa osobne pomysły z jednym operatorem, co jest niebezpieczne.
Najbardziej oczywistym przykładem tego, gdzie jest to przydatne, jest nowy unikalny_ptr. Ma wszystkie najlepsze cechy starego auto_ptr i scoped_ptr. Załóżmy, że chcemy mieć wskaźnik, który z pewnością będzie jedynym wskaźnikiem wskazującym na obiekt. Jak radzimy sobie z a = b? Cóż, wcześniej utknęliśmy, możesz albo całkowicie to zabronić (jako scoped_ptr), albo możemy zrobić to, co robi auto_ptr, gdy a = b kradnie własność z b. Takie zachowanie auto_ptr jest bardzo mylące, ponieważ a = b faktycznie zmienia b. Unique_ptr obsługuje to: a = b nie jest dozwolone, ale masz a = std :: move (b), aby ukraść własność. Jak to jest przydatne? Gdzie jest osobna (przeciążona) wersja wymiany, która używa semantyki przenoszenia zamiast semantyki kopiowania. Oznacza to, że Unique_ptr można zamienić, nie ma problemu. Oznacza to, że Unique_ptr, w przeciwieństwie do auto_ptr, można bezpiecznie używać w pojemniku, a następnie powiedzieć sort. Unique_ptr to w zasadzie całkowite i bezpieczne zarządzanie pamięcią, gdy nie potrzebujesz wielu wskaźników na tym samym obiekcie.
Kolejny świetny przykład: załóżmy, że masz obiekt, którego nie da się skopiować. Jest to przydatne w wielu sytuacjach. Nigdy nie możesz zwrócić tego obiektu z funkcji, ponieważ gdy funkcja się kończy, kopiuje to, co zwracasz. Ironiczne jest to, że zwykle kompilator faktycznie to optymalizuje (tzn. Na końcu nic nie jest kopiowane, wartość zwracana jest tworzona pod adresem ostatecznego przypisania). Ale to nie ma nic wspólnego z tym, dlaczego nie można tego skopiować; powrót z funkcji to tak naprawdę przeniesienie obiektu z zakresu funkcji na zewnątrz. Możesz teraz pisać obiekty, których nie można skopiować, ale SĄ ruchome, a obiekty te można zwrócić z funkcji.
Przestaw semantykę znacznie ułatwia pisanie kodu, który nie wycieknie i jest bezpieczny dla wątków.
źródło