Dlaczego miałbym się uczyć C ++ 11, skoro znam C i C ++? [Zamknięte]


28

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?

learning  c++  c  c++11 

3
Rozumiem, że na tym forum nie powinno być mowy o C ++ 11 i całkowicie się z tym zgadzam: każdy programista ma prawo do własnego gustu co do języków programowania i narzędzi. Jest jednak dla mnie o wiele bardziej praktyczny problem: jestem programistą C ++ i nie lubię C ++ 11, czy będę zmuszony używać C ++ 11 lub być poza rynkiem / przejść na inny język w ramach kilka lat?
Giorgio

Cóż, myślałem trochę o tym, oczywiście, że są bardziej nowoczesne języki od podstaw, takie jak język programowania D lub Go. Mogą one być odpowiednie dla Twojej problematycznej domeny, łatwiejsze, bardziej spójne itp. Jednak udział w rynku .. żaden z kluczowych graczy w branży nie obsługuje D, a nawet Go wydaje się być jednym z „eksperymentów” Google'a. Więc motywacja stojąca za C + +11 powinny być użytecznymi ulepszeniami, które pozwalają pisać lepiej czytelny, bezpieczniejszy i szybszy kod, a także wsparcie dla szerokiej branży.
Nils,

@giorgio, w ciągu ostatnich dwóch lat przestałem używać C ++ tak samo jak wcześniej (głównie z powodu uświadomienia sobie, jak religijni są fani C ++, czytając odpowiedzi na to pytanie), ale nadal pracowałem w bibliotece C ++, którą chętnie używane C ++ 11 dla. Moje doświadczenie było takie: C ++ 11 odnosi się do wielu gównianych części C ++, co jest godne podziwu i rzeczywiście poprawia się. Sposób, w jaki to robi, ma swoje gówniane rogi (patrz oryginalny, nie edytowany post). Jednak te kiepskie rogi wydają się być nie na przeszkodzie, jeśli robisz rzeczy „normalnie” (np. Nie przechowujesz lambda do przyszłego użytku).

@giorgio, mam na myśli to, że C ++ 11 może na początku wyglądać źle, w rzeczywistości samo C ++ wygląda okropnie, ale jeśli nie masz nic przeciwko C ++, prawdopodobnie też polubisz C ++ 11. Po prostu unikaj dotykania jego gównianych części i możesz się tym naprawdę cieszyć.

@anon: Jednym ze sposobów na pozbycie się gównianych części języka jest obcięcie z przeszłością i rozpoczęcie nowego języka, tak jak robi to Apple w Swift (żeby wymienić tylko jeden z wielu przykładów). Interfejs ze starszym kodem można wykonać poprzez osobną kompilację. Problem z C ++ polega na tym, że rozszerza się w nieskończoność, prawdopodobnie dlatego, że jest wspierany przez społeczność fanów, którzy religijnie wierzą, że C ++ jest jedynym prawdziwym językiem. Podsumowując: C ++ 03 uważałem za nieco nieprzyjemny, ale wykonał zadanie, szczególnie dzięki bibliotekom takim jak Qt i boost. Z drugiej strony będę trzymać ręce z dala od C ++ 11.
Giorgio

Odpowiedzi:


24

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ć.


3
Jeśli jesteś programistą „C / C ++” i jeśli twój szef każe Ci używać C ++ 11, czy nie powinieneś po prostu dodać go do swojego arsenału? Zgadzam się, że nie powinieneś poświęcać całego czasu na naukę języków tylko po to, by się ich uczyć, ale kiedy szef mówi: „Naucz się tego”, prawdopodobnie dobrym pomysłem jest kontynuowanie nauki. To także sprawia, że ​​jesteś bardziej zbywalny, a nie musisz tłumaczyć przy następnym wniosku, że zostałeś zwolniony z powodu niesubordynacji.
Panzercrisis

Haskell ... Zabawne, ponieważ powoli włącza się lambdy do C ++. : P
rbaleksandar

85

To proste. C ++ 11 sprawia, że ​​kod jest znacznie łatwiejszy, czystszy w pisaniu i szybszy.

nullptrjest ulepszeniem VAST w stosunku do starego 0. Jest bezpieczny dla typu i nie konwertuje, kiedy nie powinien - w przeciwieństwie do 0. To dobra rzecz, której nullptrnie da się przekonwertować na int. To w ogóle nie ma sensu. Czy wiesz, co znalazł Komitet C ++, gdy próbowali rozważyć #define NULL nullptr? Rzeczy jak char c = NULL;. Jak okropne to jest? Jedynym powodem, dla którego istnieje tutaj wyjątek, jest to, że booljest uważany za typ integralny, co jest całkiem błędne - ale było to wcześniej w C ++ iw C. Fakt, że nullptrnie 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_ptra shared_ptrsą o wiele lepsze niż to, co było tam wcześniej, że to niemożliwe, aby twierdzić, że C ++ 03 droga była lepsza.

#define adding_func(x, y) ((x)+(y))

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

#define add_twice(x) (x + x)

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 .

Następnie otwierasz się na świat niezdefiniowanych zachowań do używania zmiennych zewnętrznych, których zakresy są już zakończone.

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.

Weźmy na przykład C. Po tylu latach wciąż wiele osób uczy się i pisze kod w C. Dlaczego?

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.

Jeśli weźmiesz C lub stary styl C ++, nie znajdziesz wielu wyjątków.

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ń.


7
> Fakt, że nullptr nie konwertuje jest dobry, jest świetny i powinieneś go pokochać. OK, twoja opinia, ale uspokój się trochę co do tego, co ktoś powinien UWIELBIAĆ, proszę ...
Emilio Garavaglia,

5
Myślę, że w dalszej części twojej odpowiedzi jest więcej o tym, dlaczego C ++ powinien być preferowany niż C. To nie wchodzi w rachubę. „Biblioteki C są niebezpieczne” - jak, u licha, to odpowiada na pytanie? Chodzi oczywiście o to, że należy nauczyć się nowych funkcji, jakie oferuje C ++ 11, ale C i C ++ NIE są przeznaczone do robienia tych samych rzeczy. Jeśli C ++ to dziwka do zaimplementowania na niskim poziomie, to też C #, Java, Python i tak dalej , ponieważ nie były przeznaczone do tak niskiego poziomu. To, że C ++ kompiluje się do kodu natywnego, nie oznacza, że ​​możesz używać OO i powiązanego z nim thrashowania stron do krytycznego kodu na poziomie jądra.
yati sagade 9.11.11

11
@Shahbaz, oczywiście musisz nauczyć się nieco więcej o językach programowania (np. Systemach pisma, zakresach leksykalnych itp.), Wszystkie twoje komentarze są całkowicie niezsynchronizowane. Zacznij od tej książki: amazon.com/Theories-Programming-Languages-John-Reynolds/dp/…
SK-logic

5
@yati: C ++ ma ten sam system modułów co C. Funkcje składowe są implementowane jako zwykłe stare funkcje C. Funkcje wirtualne są realizowane tak samo, jak funkcje ładowania z biblioteki DLL. Nie ma w nich nic ciekawego. I tak, to zdecydowanie ma zastosowanie. Na początek twoje przekonanie, że Unix jest najlepszy, jest subiektywne. To 5% udziału w rynku sugeruje inaczej. Po drugie, nawet jeśli bez końca uwielbiałem Uniksa, jeden przykład nie ustanowi trendu. To samo dotyczy innych przytoczonych przykładów. Jakie przykłady Są bez znaczenia. C ++ jest tak samo odpowiedni do procedur jak C.
DeadMG,

8
@yatisagade C ++ jest językiem opartym na wielu paradygmatach, który nie wymusza wirtualnych funkcji dla wszystkiego, a moje programy w C ++ są podobne. Jego części wykorzystują projektowanie obiektowe, części funkcjonalne itp., W zależności od tego, co najlepiej rozwiązuje ten konkretny problem. Doceniam C ++ za dodanie stylu obiektowego i doceniam C ++ 11 za znaczne rozszerzenie obsługi programowania funkcjonalnego.
David Stone

29

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.


7
@Shahbaz - Myślę, że nadal nie masz zamiaru, dlaczego dodano funkcje bezimienne. A „używanie zmiennych bez przyjmowania ich jako danych wejściowych” nazywa się zamknięciem i jest dostępne w wielu innych językach wysokiego poziomu. Jeśli napisałeś dużo kodu szablonu z obiektami funktorów, w C ++ 11 powitałbyś funkcje lambda z otwartymi ramionami. Pomyśl o tym w ten sposób ... kiedy kompilator generuje kod maszynowy, nie ma czegoś takiego jak funkcja szablonu lub klasa. Wszystkie są „tworzone” w celu utworzenia konkretnych klas / funkcji przed tym punktem. Lambda to to samo, jeśli chodzi o stanowe ...
DXM,

5
... funktory. Zamiast zmuszać ludzi do pisania ton kodu, po jednym dla każdego rodzaju funktora i każdego elementu zamknięcia, który chcesz przekazać, C ++ 11 pozwala ci określić składnię skrótu i ​​automatycznie utworzy instancję całej wewnętrznej klasy funktorów, tak jak tworzy szablony. Ponownie pamiętaj, że większość tych funkcji nie będzie wykorzystywana w 98% kodu na poziomie aplikacji, ale zostały one dodane, aby biblioteki takie jak STL / Boost były znacznie wydajniejsze i łatwiejsze do wdrożenia / utrzymania / debugowania
DXM

10
@Shahbaz: Dobra, nie rozumiesz funkcji i zamknięć lambda. To uzasadnione. Fakt, że są używane w wielu różnych językach, powinien sugerować, że są one użyteczne, niezależnie od tego, czy je rozumiesz, czy też powinieneś je zrozumieć, zanim za bardzo je skrytykujesz.
David Thornley,

8
@Shahbaz: Jeśli uważasz, że zamknięcia są podobne do zmiennych globalnych, nie rozumiesz zamknięć. (Wskazówka: zmienne globalne powodują problemy, ponieważ każda funkcja może je modyfikować.) Jeśli rozumiesz pojęcie lambdów, a nie implementację, nie przypisujesz jej pomieszaniu klas z kodem. Wszystko w standardzie C ++ istnieje z powodów, które przekonały dużą liczbę inteligentnych ludzi. Nie musisz zgadzać się z powodami, ale nie znając ich, krytykujesz ignorancję.
David Thornley,

6
@Shahbaz, absolutnie nie ma podobieństwa między zamknięciami a globałami, zupełnie nie rozumiesz sedna sprawy. Przeczytaj to: en.wikipedia.org/wiki/Lambda_calculus i wysadzić mózg: en.wikipedia.org/wiki/Combinatory_logic
SK-logic

18

Czy tak trudno jest napisać funkcję, że trzeba napisać zawartość funkcji zgodnie z kodem, poza tym, że nie ma nazwy?

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

Dlaczego nie napiszesz tam kodu zamiast uczynienia go funkcją lambda?

Ponieważ nie możesz tego zrobić, gdy używasz algorytmów STL lub jakiejkolwiek funkcji, której używasz, która wymaga przekazania funkcji.

# zdefiniować dodanie_funkcji (x, y) ((x) + (y))

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.

template<class Lhs, class Rhs>
auto adding_func(const Lhs &lhs, const Rhs &rhs)
                -> decltype(lhs+rhs) {return lhs + rhs;}

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.


Argumenty na temat samodokumentowania i mniej przewijania itp., Jestem prawie pewien, że przeciwne argumenty, takie jak „zaśmiecony kod”, „ograniczający dostęp” itp. Były kiedyś używane do argumentowania, dlaczego funkcje poza klasą muszą być zakazane. Myślę, że ludzie muszą mieć większe doświadczenie, aby decydować, które z nich jest lepsze. Wydaje mi się, że to albo nieudany eksperyment, albo zły projekt. Jestem bardziej przekonany, że nie będę szczurem laboratoryjnym w tym eksperymencie.
Shahbaz

Jeśli chodzi o składnię wyglądającą brzydko, weźmy te dwa na przykład: bool is_alive;i bool 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.
Shahbaz,

3
dobrze wygląda! = dobrze i źle wygląda! = źle.
DeadMG,

@Shahbaz: Myślę, że lambdas są świetnymi pomysłami (i istnieją od wielu lat w językach takich jak Lisp). Często używam ich w Haskell. Nie jestem pewien, czy pasują do języków takich jak C ++, Java itp. Czuję się trochę jak po refleksji: coś, co zostało dodane później, ponieważ lambdas stały się popularne. Dlaczego nie zostały wprowadzone w tych językach od samego początku? Czy Stroustrup i Goslin nigdy nie słyszeli o Lisp?
Giorgio

8

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ównież się zgadzam. A jako programista bardzo przeszkadza mi język, który cały czas się zmienia (muszę się ciągle uczyć). Jeśli opracujesz nowy język, powinieneś zacząć od nowa i użyć innej nazwy. Jeśli chcesz, aby współpracował ze starszym kodem, istnieje do tego osobna kompilacja. Naprawdę więc nie rozumiem zasady zmiany istniejącego języka poprzez włączenie najnowszych funkcji, które stały się modne. Jak ktoś powiedział: dalszy rozwój nie oznacza automatycznie postępu.
Giorgio

„C ++ po prostu nie można uprościć w tym sensie. Nie w tym wieku.”: Dlaczego inne języki programowania (np. C, Ada, ...) nie podążają tą samą ścieżką? Może dlatego, że mają własną niszę aplikacji i nie oczekuje się, że będą narzędziem dla wszystkich możliwych obszarów zastosowań.
Giorgio

@giorgio: tak ... prawdopodobnie masz rację w sensie „pragmatycznym”. Ale teoretycznie ... pamiętam kilka dobrych dni, w których pascal był „nauczającym językiem odniesienia”, a ada „wszystkim, którzy chcą języka programowania”.
Emilio Garavaglia

Nauczyłem się także programowania w Pascal. O ile mi wiadomo, Ada przeszła kilka poprawek, ale podstawowy projekt języka nie został naruszony. To samo dotyczy C i Pascala. Jeśli ktoś chce opracować naprawdę nowy język, powinien być wystarczająco odważny, aby dokonać wyraźnego cięcia i rozpocząć coś nowego, np. D, Java, C #. Mój problem z obecną ścieżką, którą podąża C ++, jest (niepotrzebnie) zbyt skomplikowany. Jeśli zasady KISS i YAGNI mają zastosowanie do projektowania oprogramowania, dlaczego nie powinny mieć zastosowania również do projektowania języka programowania?
Giorgio

@Giorgio: och ... mają zastosowanie ... dokładnie tak jak powiedziałeś. Jeśli uważasz, że C # lub D dokonały lepszego wyboru niż „ugotowane” C ++ (moja interpretacja twoich uczuć), po prostu użyj ich zamiast C ++. W miarę upływu czasu w C ++ powoli umiera. W tej chwili widzę, że C ++ 11 daje nową szansę „gotowanemu” C ++ 03, a D wciąż brakuje czegoś, aby przełamać barierę początkową. Ekonomia i interesy korporacji również odgrywają rolę w finansowaniu i wspieraniu rozwoju. Masz rację w teorii, ale świat rzeczywisty jest bardziej złożony.
Emilio Garavaglia

7

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.


6

Po tylu latach wciąż wiele osób uczy się i pisze kod w C. Dlaczego? Ponieważ język jest dobry.

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ć.


Niecałkowicie zacytowałeś moje zdanie. Jak powiedziałem w goodnastę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).
Shahbaz

1
@Shahbaz: Cytuję pełne zdania. Nawiązałeś związek przyczynowy, a ja powiedziałem, że jest w najlepszym razie niekompletny. Na szczęście już się nie uczę. :) Zrobiłem dość tego. Mieszkam w USA, a kiedy poszedłem na studia (ponad 15 lat temu) C był językiem wprowadzającym. Jednak dziś większość amerykańskich szkół zaczyna się od Java i nie ma zbyt wielu młodych programistów, którzy znają C.
Dima,

5
@Shahbaz: Naprawdę nie widzę problemu z regułami językowymi mającymi wyjątki. Tak, C jest znacznie prostszym językiem niż C ++. Z drugiej strony C ++ ułatwia pisanie prostszego kodu. Aby napisać prostszy kod, potrzebujesz więcej funkcji językowych. To sprawia, że ​​język jest bardziej złożony. Ja, na przykład, lubię takie rzeczy jak klasy, referencje, RAII, szablony, konstruktory, destruktory, wyjątki i przestrzenie nazw. Ale powiedziałeś, że twoje pytanie nie dotyczyło C vs. C ++, więc nie napisałem o tym w odpowiedzi.
Dima

5
  • Asembler został stworzony, ponieważ ludzie nie lubili pisać kodu maszynowego
  • C został stworzony, ponieważ ludzie nie lubili pisać asemblera
  • C ++ został stworzony, ponieważ ludzie nie lubili pisać C.
  • C ++ 11 został stworzony, ponieważ ludzie nie lubili pisać C ++

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.


Wszystkie języki zostały utworzone, ponieważ ktoś nie lubił istniejących. To nie czyni żadnego z nich dobrym.
Shahbaz

Nie twierdzę, że NULLpowinien 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.
Shahbaz

2
„C ++ 11 został stworzony, ponieważ ludzie nie lubili pisać C ++”: jeśli nie lubili pisać C ++, dlaczego C ++ jest podzbiorem C ++ 11?
Giorgio

1
Powinno to być: C # i Java została stworzona, ponieważ ludzie nie lubili pisać C ++.
Calmarius

4

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.


4

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.


A przy okazji, wydajne.
Nir Friedman,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.