C++

Wikipediasta
Siirry navigaatioon Siirry hakuun
C++
ISO C++ Logo.svg
Paradigma moniparadigmainen; proseduraalinen, olio-ohjelmointi, geneerinen, funktionaalinen
Tyypitys vahva, staattinen
Yleinen suoritusmalli käännettävä
Muistinhallinta manuaalinen, RAII
Julkaistu 1983
Kehittäjä Bjarne Stroustrup
Vakaa versio ISO/IEC 14882:2020
Merkittävimmät toteutukset GCC, Visual C++, LLVM/Clang, Intel C/C++, Borland C++, IBM XL C++
Vaikutteet C, Ada, Simula, CLU
Vaikuttanut Java, C99, D, C#, Rust
Käyttöjärjestelmä alustariippumaton
Verkkosivu https://isocpp.org/
Uutisryhmä comp.lang.c++

C++ on ohjelmointikieli, jonka Bjarne Stroustrup kehitti 1980-luvulla. Kieli on kehitetty C-kielestä lisäämällä siihen muun muassa olio-ohjelmointiin ja geneerisyyteen liittyviä ominaisuuksia.[1][2]

C++-kielen standardi ISO/IEC 14882:1998 vahvistettiin vuonna 1998,[3] C++11 (ent. C++0x) vuonna 2011,[4] C++14 (ISO/IEC 14882:2014) vuonna 2014.[5] Uusin standardi ISO/IEC 14882:2017 (C++17) on valmistunut vuonna 2017.[6]

C++ sisältää muun muassa luokat, virtuaalisen moniperintätuen, mallit (templates) ja poikkeukset. C++ perustuu C-kieleen siten, ettei kieltä ole suunniteltu uudelleen, vaan uusia ominaisuuksia on lisätty.[7] Kieli on moniparadigmainen, mahdollistaen muun muassa proseduraalisen-, olio- ja geneerisen ohjelmoinnin.[8] Kieli ei ole täysin funktionaalisen ohjelmoinnin kieli, mutta mahdollistaa monia vastaavia käyttötapoja.[9][10]

Muistinhallinta perustuu RAII (engl. Resource acquisition is initialization) -konseptiin, joka soveltuu muun muassa käyttöön poikkeuksien kanssa.[11]

C++:lla on kirjoitettu suuri osa maailman ohjelmistoista, mukaan lukien käyttöjärjestelmät, lääketieteelliset ohjelmistot, simulointiohjelmistot, finanssialan ohjelmistot, tietokoneavusteisen suunnittelun ohjelmistot, sulautetut järjestelmät, tietokoneverkot, ja videopeliohjelmistot (mm. pelimoottorit).[12] TIOBE:n vuosittain päivittyvässä indeksissä C++ oli neljänneksi yleisin ohjelmointikieli huhtikuussa 2021.[13]

Historia ja vaikutteet[muokkaa | muokkaa wikitekstiä]

C++:n kehitys alkaa vuodesta 1979, jolloin Bjarne Stroustrup työskenteli tohtorintutkinnon parissa.[14] Tuolloin Stroustrup työskenteli muun muassa Simula-kielellä, jonka sanotaan olevan ensimmäinen olio-ohjelmoinnin paradigmaa tukeva kieli.[14] Stroustrup koki paradigman hyvin käytännölliseksi, mutta kielen liian hitaaksi käytännölliseen soveltamiseen.[14] Tämän jälkeen Stroustrup aloitti C with Classes -laajennuksen kehittämisen C-kieleen.[14] Vuonna 1983 kielen nimi vaihtui C++:ksi.[14]

C++:n luokat ja luokkahierarkia on peräisin Simulasta.[15] Kieli lainasi myös suunnitteluajattelun, jossa luokat mallintavat käsitteitä ohjelmoijan ja sovelluksen maailmassa eivätkä ainoastaan notaationaalisessa merkityksessä.[15]

Kielen suunnittelussa vältettiin ominaisuuksia, jotka aiheuttaisivat ajonaikaista tai muistikuormitusta.[16]

Kehitysvaiheet[muokkaa | muokkaa wikitekstiä]

Kielestä on julkaistu useita kehitysversioita:

  • C++98 (ISO/IEC 14882:1998) oli kielen ensimmäinen ISO-standardoitu versio.
  • C++03 sisälsi korjauksen std::vector määrittelyyn, jonka mukaan elementtien käyttämä muistialue on oltava jatkuva (joka takaa yhteensopivuuden perinteisempien taulukoiden kanssa).[17]
  • C++11 lisää tuen mm. säiekohtaiselle muistille (thread_local-avainsanalla) sekä säikeistykselle yleisesti.[18] Standardikirjastoon lisättiin uudet älyosoittimet, kuten std::shared_ptr (toteuttaa viitelaskennan).
  • C++14 lisää tuen mm. lambda-funktioille eli anonyymeille inline-funktioille.
  • C++20 äänestettiin valmiiksi 15. helmikuuta 2020.[19]
  • C++23 on seuraava versio, jota kehitetään C++20:n seuraajaksi[20]

ISO-standardit[muokkaa | muokkaa wikitekstiä]

C++ ISO/IEC standardista on julkaistu seuraavat versiot:

  • ISO/IEC 14882:1998 (1998)[3]
  • ISO/IEC 14882:2003 (2003)[21]
  • ISO/IEC 14882:2011 (2011)[4]
  • ISO/IEC 14882:2014 (2014)[5]
  • ISO/IEC 14882:2017 (2017)[6]
  • ISO/IEC 14882:2020 (2020)[22]

Tekniset määrittelyt[muokkaa | muokkaa wikitekstiä]

Virallisten standardien lisäksi ISO-työryhmällä on eräitä teknisiä määrittelyjä, jotka eivät ole vielä varsinaisen standardin tasolla ja jotka ovat vielä muuttuvia.

Esimerkkinä N4514, joka määrittelee transaktiopohjaisen muistin käsittelyn tuen C++-kieleen.[23] Osa ohjelmointikielen kääntäjistä tarjoaa kokeellisen tuen kuten esimerkiksi GCC.[24]

ISO:n julkaisemia määrittelyjä:

  • ISO/IEC TR 18015:2006[25]
  • ISO/IEC TR 19768:2007[26]
  • ISO/IEC TR 29124:2010[27]
  • ISO/IEC TR 24733:2011[28]
  • ISO/IEC TS 18822:2015[29]
  • ISO/IEC TS 19570:2015[30]
  • ISO/IEC TS 19841:2015[31]
  • ISO/IEC TS 19568:2015[32]
  • ISO/IEC TS 19217:2015[33]

Standardidokumenttien saatavuus[muokkaa | muokkaa wikitekstiä]

Virallinen standardi on saatavissa ISO:lta korvausta vastaan, mutta viimeisin työskentelyluonnos on saatavilla julkisesti ilmaiseksi.[34] Virallisessa standardissa on korjattu kirjoitusvirheitä ja lisätty selvennyksiä.

Standardidokumentit eivät ole tarkoitettu oppaaksi kielen oppimiseen, vaan ne ovat formaaleja sopimuksia kääntäjien ja standardikirjastojen kehittäjille.[34]

Erot C:hen[muokkaa | muokkaa wikitekstiä]

Monet C-kielellä kirjoitetuista ohjelmista ovat myös kelvollista C++:aa.[16], mutteivat kuitenkaan kaikki C:n kehittymisen aikana luotujen uusien varattujen sanojen ja tarkemman tyyppitarkistuksen vuoksi. C++ kuitenkin laajentaa C:tä huomattavasti, muun muassa nimiavaruustuella,[35] isommalla standardikirjastolla, luokilla sekä malleilla.

Standardikirjastot[muokkaa | muokkaa wikitekstiä]

C++ sisältää Standard Template Library (STL) -standardikirjaston. Se sisältää yleisiä ohjelmoijien tarvitsemia säiliöitä (containers), algoritmeja, funktioita ja iteraattoreita. STL-toteutus tulee yleensä kääntäjän mukana, mutta myös riippumattomia toteutuksia on olemassa.

C++:n standardikirjasto sisältää STL:n lisäksi myös suurimman osan C-kielen standardikirjastosta yhteensopivuuden vuoksi.[36]

Polymorfismi[muokkaa | muokkaa wikitekstiä]

C++ tukee yksinkertaista perintää, abstrakteja pure virtual -luokkia, moniperintää sekä virtuaalista moniperintää.[37][38][39]

Rajapinnan perimistä kutsutaan ajonaikaiseksi polymorfismiksi (tai dynaamiseksi polymorfismiksi) ja template-mallien tukemaa käännösaikaiseksi polymorfismiksi (tai staattiseksi polymorfismiksi).[40]

C++:ssa funktiot voidaan määritellä:[41]

  • virtual, jolloin se voidaan syrjäyttää perityssä luokassa
  • override, jolloin sen on pakko syrjäyttää kantaluokassa oleva
  • final, jolloin sitä ei voida syrjäyttää perityssä luokassa

Hello, World! -esimerkkiohjelma[muokkaa | muokkaa wikitekstiä]

#include <iostream>

int main() {
    std::cout << "Hello, world!\n";
}

Tämä on yleisesti käytetty esimerkkiohjelma C++-oppaissa. Se tulostaa näytölle tekstin ”Hello, world!” Kuten C:ssä, ohjelma alkaa komennoilla esikääntäjälle, tässä otsikkotiedoston liittämisellä #include-käskyllä. Lohkot rajataan aaltosuluilla {} ja ohjelma suoritetaan kutsumalla main-funktiota. Ohjaamalla teksti cout-olioon <<-operaattorilla teksti tulostuu stdout-virtaan (näytölle). C++:n tulostuslauseen epätavallinen syntaksi johtuu kielen tukemasta operaattorien uudelleenmäärittelystä. C-kielen bittisiirto-operaattori << on C++:ssa määritelty virtaolioilla kirjoitusoperaattoriksi, ja tässä tapauksessa se kirjoittaa standarditulosteeseen.

C++:n kielioppi on samantapaista kuin C:n ja Javan. Lauseet päättyvät puolipisteeseen ;, eikä välilyöntejä tai muuta tyhjää tilaa oteta huomioon. Lohkot ympäröidään aaltosulkeilla { }, kommentit aloitetaan /* -merkinnällä ja päätetään */ -merkinnällä. Yhden rivin kommentti merkitään kahdella vinoviivalla //. Kaikki standardikirjaston luokat, funktiot ja enumeraatiot ovat std-nimiavaruudessa.

Nimiavaruudet[muokkaa | muokkaa wikitekstiä]

C++ tukee useaa nimiavaruutta.[35] C++17 lisäsi tuen sisäkkäisille nimiavaruuksille, joka mahdollistaa namespace A::B::C {} käytön aiemman namespace A { namespace B { namespace C {}}} sijaan.[42] Lisäksi kieli tukee nimiavaruuden aliasointia:[43]

namespace foo {
    namespace bar {
         namespace baz {
             int qux = 42;
         }
    }
}
namespace fbz = foo::bar::baz;
int main()
{
    std::cout << fbz::qux << '\n';
}

C++ tukee myös anonyymejä nimiavaruuksia.[44]

Aaltosuluilla merkittävät lohkot luovat oman nimiavaruuden kaltaisen näkyvyysalueen (engl. scope):[45]

std::string foo = "foo";
{
    std::string foo = "foobar";

} // sisempi foo tuhotaan tässä

std::cout << foo << std::endl; // tulostaa ensimmäisen foo:n arvon

RTTI[muokkaa | muokkaa wikitekstiä]

Ajonaikainen tyyppitieto (engl. Run-time type information, RTTI) on ominaisuus, jolla välitetyn olion tyyppi voidaan tunnistaa ohjelman ajon aikana. Tämä mahdollistaa muun muassa perityn olion tyypin mukaisen käsittelyn.

class Asiakas
{
public:
    virtual ~Asiakas() {}
}

class KantaAsiakas : public Asiakas { ... };

void tyyppi(Asiakas *p)
{
    std::cout << typeid(*p).name() << std::endl;
    // tulostaa olion p tyypin nimen. tarkka muoto riippuu kääntäjästä.

    KantaAsiakas *k = dynamic_cast<KantaAsiakas*>(p);
    if (k != nullptr)
        k->bonus();
}

Poikkeusten käsittely[muokkaa | muokkaa wikitekstiä]

C++ tukee poikkeuksia ja pinon (stack) siivoamista (kuten näkyvyysalueelta eli scopesta poistuessa).

try
{
    throw "vikatilanne"; // const char *
}
catch (std::exception &e)
{
    std::cout << "poikkeus: " << e.what() << std::endl;
}
catch (...)
{
    std::cout << "tuntematon poikkeus" << std::endl;
}

Poikkeuskäsittelijä valitaan määrittelyjärjestyksessä ja tyypin mukaan.[46] Poikkeuskäsittely try-lohkolla ja throw-operaattorilla on valinnaista, jolloin niiden aiheuttama lisäkuorma voidaan välttää.[16]

Ellipsis (kolme pistettä) voi vastaanottaa tyypit, joille ei ole määritelty muuta käsittelijää.

RAII[muokkaa | muokkaa wikitekstiä]

Konseptia, jossa resurssit varataan konstruktorissa ja vapautetaan destruktorissa kutsutaan nimellä engl. Resource acquisition is initialization, RAII. Konseptin ovat kehittäneet Bjarne Stroustrup ja Andrew Koenig vuosina 1984–1989 ja se on esitelty ensimmäisenä C++-kielessä.[47]

RAII-muistihallintakonsepti voidaan esittää seuraavan triviaalin esimerkin avulla:[48]

class Vector 
{
private:
    double *elem; 
    int sz;
public:
    Vector(int s) : elem{new double[s]}, sz{s} // constructor
    {
        for (int i = 0; i != s; ++1) elem[i] = 0;
    }
    ~Vector() { delete [] elem; } // destructor

    double& operator[](int i);
    int size() const { return sz; }
};

void fct(int n) 
{
    Vector v(n); // acquire and initialize
    // .. use v ..
    {
        Vector v2(n*2); // acquire and initialize
        // .. use v2 ..
    } // v2 destroyed
    // .. use v ..
} // v destroyed

Esimerkissä resurssit vapautetaan kutsumalla olion destruktoria:

  1. poikkeustapauksessa
  2. normaalisti poistuessa (näkyvyysalueen ulkopuolella)

Olion luominen tekee tarvittavan varauksen ja alustuksen, jotka olion destruktori vapauttaa. Menetelmä on poikkeusturvallinen eikä tarvitse roskienkeräystä tueksi.

Template-mallit[muokkaa | muokkaa wikitekstiä]

C++ tukee suoraan geneeristä ohjelmointia template-malleilla, joille voidaan antaa tyyppi parametrina.[49] Mallit mahdollistavat geneerisen ohjelmoinnin, jossa samoja algoritmeja voidaan käyttää uusille tietotyypeille ilman erillisen toteutuksen kirjoittamista joka tyypille.

RAII-esimerkin ohjelmakoodi voidaan muokata geneerisemmäksi käyttämällä template-määrittelyä.

template<typename T> class Vector 
{
private:
    T *elem; 
    int sz;
public:
    Vector(int s) : elem{new T[s]}, sz{s} // constructor
    {
        for (int i = 0; i != s; ++1) elem[i] = 0;
    }
    ~Vector() { delete [] elem; } // destructor

    T& operator[] (int i) { return elem[i]; }
    int size() const { return sz; }
};

void fct(int n) 
{
    Vector<double> v(n); // acquire and initialize
    // .. use v ..
    Vector<int> v2(n)
    // .. use v2 ..

} // v2 and v destroyed

Katso myös[muokkaa | muokkaa wikitekstiä]

Lähteet[muokkaa | muokkaa wikitekstiä]

  • Stroustrup, Bjarne: The design and evolution of C++. Addison-Wesley, 1994. ISBN 0-201-54330-3.
  • Lippman, Stanley B.: C++ Primer, s. 1–464. Addison-Wesley, 1989. ISBN 0-201-16487-6.
  • Reisdorph, Kent: Teach Yourself C++ in 5 Days, s. 1–192. SAMS, 1999.
  • Hietanen, Päivi: C++ ja olio-ohjelmointi, s. 16. Jyväskylä: Teknolit, 1997. ISBN 952-9823-45-2.
  • Peltonen, Hannu: Olio-ohjelmoinnin perusteet C++, s. 1–389. Jyväskylä: Suomen ATK-kustannus, 1997. ISBN 951-762-457-3.
  • Prata, Stephen: Suuri C++ -ohjelmointi, s. 1–866. Suomentanut Risto Torkkeli. Vantaa: Pagina, 1996. ISBN 951-644-064-9.
  • Horton, Ivor: C++ Ohjelmoijan käsikirja, s. 1–941. Suomentanut Jouni Laaksonen. Helsinki: IT Press, 1999. ISBN 951-826-032-X.
  • Lippman, Stanley B. & Lajoie, Josee: C++ Vol 1, s. 1–941. Suomentanut Erkki Huru. Helsinki: EDITA, 2000. ISBN 951-826-191-1.
  • Meyers, Skott: C++ Vol 2, s. 1–256. Suomentanut Arto Kuvaja. Helsinki: EDITA, 2000. ISBN 951-826-192-X.
  • Stroustrup, Bjarne: The C++ Programming Language, 4th ed.. Addison-Wesley, 2015. ISBN 0-321-56384-0.

Viitteet[muokkaa | muokkaa wikitekstiä]

  1. Stroustrup 1994, s. 63–108
  2. Bjarne Stroustrup: Evolving a language in and for the real world: C++ 1991–2006 stroustrup.com. Viitattu 1.2.2017.
  3. a b ISO/IEC 14882:1998 ISO. Viitattu 25.1.2017.
  4. a b ISO/IEC 14882:2011 ISO. Viitattu 25.1.2017.
  5. a b ISO/IEC 14882:2014 ISO. Viitattu 25.1.2017.
  6. a b ISO/IEC 14882:2017 ISO. Viitattu 5.12.2017.
  7. Hietanen 1997, s. 16
  8. Stroustrup 2015, s. 11
  9. David Cravey: C++ - Functional-Style Programming in C++ docs.microsoft.com. elokuu 2012. Viitattu 25.2.2020. (englanniksi)
  10. John Carmack: In-depth: Functional programming in C++ gamasutra.com. 30.4.2012. Viitattu 25.2.2020. (englanniksi)
  11. Bjarne Stroustrup: Bjarne Stroustrup's C++ Style and Technique FAQ stroustrup.com. Viitattu 26.1.2017.
  12. https://www.stroustrup.com/applications.html
  13. https://www.tiobe.com/tiobe-index/
  14. a b c d e History of C++ cplusplus.com. Viitattu 21.2.2020. (englanniksi)
  15. a b Stroustrup 2015, s. 577
  16. a b c Stroustrup 2015, s. 15
  17. C++ Standard Library Defect Report List (Revision R101) open-std.org. Viitattu 29.1.2017.
  18. Programming Languages – C++11 Draft (n3797) §3.7.2 Thread Storage duration [basic.stc.thread]
  19. Bjarne Stroustrup on C++20's significance isocpp.org. 21.2.2020. Viitattu 25.2.2020. (englanniksi)
  20. To boldly suggest an overall plan for C++23 open-std.org. 25.11.2019. Viitattu 11.3.2020. (englanniksi)
  21. ISO/IEC 14882:2003 ISO. Viitattu 25.1.2017.
  22. ISO/IEC 14882:2020 ISO. Viitattu 6.3.2021.
  23. Technical Specification for C++ Extensions for Transactional Memory open-std.org. Viitattu 7.3.2017.
  24. C++ Standards Support in GCC gcc.gnu.org. Viitattu 7.3.2017.
  25. ISO/IEC TR 18015:2006 International Organization for Standardization.
  26. ISO/IEC TR 19768:2007 International Organization for Standardization.
  27. ISO/IEC TR 29124:2010 International Organization for Standardization.
  28. ISO/IEC TR 24733:2011 International Organization for Standardization.
  29. ISO/IEC TS 18822:2015 International Organization for Standardization.
  30. ISO/IEC TS 19570:2015 International Organization for Standardization.
  31. ISO/IEC TS 19841:2015 International Organization for Standardization.
  32. ISO/IEC TS 19568:2015 International Organization for Standardization.
  33. ISO/IEC TS 19217:2015 International Organization for Standardization.
  34. a b The Standard isocpp.org. Viitattu 25.2.2020. (englanniksi)
  35. a b Namespaces en.cppreference.com. Viitattu 28.7.2018.
  36. C++ Standard Library headers en.cppreference.com. Viitattu 5.3.2020. (englanniksi)
  37. Solving the Diamond Problem with Virtual Inheritance Cprogramming.com. Viitattu 8.2.2017.
  38. Inheritance – Multiple and Virtual Inheritance isocpp.org. Viitattu 8.2.2017.
  39. Derived classes en.cppreference.com. Viitattu 8.2.2017.
  40. Stroustrup 2015, s. 578
  41. Stroustrup 2015, s. 307
  42. Nested namespace definition (revision 2) open-std.org. Viitattu 3.3.2017.
  43. Namespace aliases en.cppreference.com. Viitattu 28.7.2018.
  44. Unnamed namespaces (C++ only) IBM. Viitattu 28.7.2018.
  45. Scope en.cppreference.com. Viitattu 28.7.2018.
  46. Stroustrup 2015, s. 370
  47. Stroustrup, Bjarne 2015: The C++ Programming Language, 4th ed: kpl13, s. 343–387
  48. Stroustrup, Bjarne 2015: The C++ Programming Language, 4th ed: kpl3, s. 63
  49. Stroustrup 2015, s. 665

Kirjallisuutta[muokkaa | muokkaa wikitekstiä]

  • Stroustrup, Bjarne: The C++ Programming Language, s. 1–328. Addison-Wesley, copyright Bell laboratories, 1986. ISBN 0-201-12078-X.
  • Stroustrup, Bjarne: The C++ Programming Language, s. 1–911. Third Edition, Bjarne Stroustrup The Creator of C++. Addison-Wesley, copyright AT&T, 1997. ISBN 0-20-88954-4.
  • Stroustrup, Bjarne: C++ -ohjelmointi, s. 1–944. Alkuteos The C++ Programming Language, Third Edition, Bjarne Stroustrup The Creator of C++. Suomentanut Veli-Pekka Ketola. Jyväskylä: Teknolit, copyright AT&T, copyright Teknolit, 2000. ISBN 951-846-026-4.

Aiheesta muualla[muokkaa | muokkaa wikitekstiä]

Commons
Wikimedia Commonsissa on kuvia tai muita tiedostoja aiheesta C++.
Käännös suomeksi
Tämä artikkeli tai sen osa on käännetty tai siihen on haettu tietoja muunkielisen Wikipedian artikkelista.
Alkuperäinen artikkeli: en:Resource acquisition is initialization