O wadach języka C++

Opublikowane: 02/12/2014

w kategorii Zasoby.

Każdy język programowania ma jakieś wady. Niektórzy mówią "C++ naprawia problemy które sam tworzy". Nie możesz powiedzieć że znasz język lub narzędzie bez znajomości jego wad. Dlatego poniżej przedstawiam niektóre z nich.

List problemów ważnych dla mnie:

1) Brak modułów

Pascal ma unity. Python - moduły. W C/C++ jest inaczej. Potrzebujesz pewnych dodatkowych konstrukcji ("idiomów") aby wykonać coś co jest wbudowane w innych językach.

  • interfejs modułu (nagłówek) potrzebuje "strażników nagłówka" aby poprawnie skompilować część wywołującą i wywoływaną
  • moduł nie może mieć prywatnych części (współdzielonych przez kilka klas), musisz użyć idiomu PIMPL lub słabszego rozwiązania - przestrzeni nazw "details"
    namespace my_net_lib
    {
      int open_connection();
      int close_connection();
    
      namespace details
      { 
        // ta część jest zabroniona do wykorzystania poza biblioteką (umownie)
        int is_proxy_connection();    
      }
    }
    

Uwaga: jest propozycja naprawy modułów w C++: WG21 SG2 (Modules)

Zobacz:

2) Wsparcie dla łańcuchów jest słabe

  • łańcuchy są wspierane na dwa sposoby - mogą być przekazane jako "const char[]" lub "const std::string &"
  • literał jak "test" nie jest typu std::string, to tylko "const char[]", dlatego dodatkowe przetwarzanie (kopia) jest wymagane jeśli wołasz funkcje z literałami
  • przeciążenie funkcji z argumentem "void *" jest preferowane zamiast tej samej funkcji z argumentem "std:string" jeśli przekazujesz literał
  • wsparcie dla Unicode nie jest kompletne - zobacz Unicode

3) Musisz pamiętać o wielu pułapkach które język Ci "dostarcza":

a) deklaracja funkcji zamiast konstrukcji obiektu

void foo()
{
    // deklaruje funkcję x zamiast stworzyć obiekt x
    List x();   
}

b) wyciek pamięci w klasach pochodnych ponieważ klasa bazowa nie miała wirtualnego destruktora

Zobacz C++ language feature: virtual destructor

c) wyliczenia (enum) mogą zawierać nieunikalne wartości

4) Iteratory nie mogą zawierać polimorficznych części (zaalokowanych na stercie) ponieważ:

a) są przekazywane przez wartość w STL

b) to zwalnia przetwarzanie BARDZO

5) Brakuje przenośnego interfejsu bibliotek

Biblioteki skompilowane innym kompilatorem lub z innymi ustawieniami kompilatora nie mogą być użyte w tym samym projekcie. Biblioteki dynamiczne ułatwiają życie ale nadal nie mogą przekazywać wyjątków czy std::string z DLL do głównego programu jeśli skompilowane przez innego dostawcę. I biblioteki dynamiczne nie wspierają OOP. Tak więc musisz stosować programowanie strukturalne kiedy implementujesz API.

Obejście - zastosuj DynObj od Arne Steinarson (CodeProject), 2007

6) Zachowania niezdefiniowane

Termin zdefiniowany dla C/C++ - zobacz UB. Może powodować pojawianie się błędów spowodowanych agresywną optymalizacją kompilatora, błędy które mogą być wykryte... przez kompilator (Clang).

7) przynajmniej pięć form przekazywania obiektów:

  • przez wartość (jak np. iteratory)
  • jako zwykłe wskaźniki (ze słowem kluczowym "const" tworzy to 3 dodatkowe formy)
  • jako sprytne wskaźniki
  • jako referencje
  • jako referencje z const

W Javie: jeden sposób (przez referencję).

Zasoby

Udostępnij

obserwuj