C++ pamoka C vartotojams

Šis tekstas rodo ir pabrėžia savybės ir pagrindiniai principai C++. Jis skirtas patyrusiems C vartotojams, kurie nori išmokti C++. Jūs galėsite išreikšti savo kodą naudodamiesi turtingesnė C++ sintaksę ir jūs galėsite skaityti kai C++ kodą.

Nors sąvoka yra įdiegta ir padarė naudoti, tai ne pamoka apie Objektinis programavimas. Jūs vis dar turite išmokti OOP dvasią ir jos įgyvendinimo C++ detales, kad būtų tiesa, C++ programuotojas.

Jei jūs neturite C++ kompiliatorius po ranka, gal pabandyti naudotis interneto priemones, pavyzdžiui, tai vienas: http://codepad.org


1.

Yra naujas būdas #include bibliotekas (senas metodas vis dar veikia dar sudarytojas skundžiasi). .h plėtinys nėra naudojamas, bet daugiau, ir standartinės C bibliotekų pavadinimai rašomi pradedant nuo .c. Tam, kad programa naudoti šias bibliotekas teisingai using namespace std; turi būti pridėta:

using namespace std;
#include <iostream> // This is a key C++ library
#include < cmath> // The standard C library math.h

int main ()
{
double a;

a = 1.2;
a = sin (a);

cout << a << endl;

return 0;
}


Output
0.932039

Keletas patarimų pradedantiesiems:

Sudaryti šią programą, įveskite jį (arba nukopijuokite & įklijuokite jį) į tekstinį redaktorių (gedit, Kwrite, Kate, kedit, VI, Emacs, nanotechnologijų, Piko, mcedit, Užrašų knygelė...), išsaugokite jį kaip failą, pavadintą, pasakyti test01.cpp (jei esate naujokas, geriausias įdėti šį failą viduje jūsų namų katalogą, kad yra, pavyzdžiui /home/jones Unix dėžutėje).

Kompiliuoti kodo failą, įveskite šią komandą (daugumoje atviro kodo Unix dėžės) A konsolės ar terminalo lange:

g++ test01.cpp -o test01

Norėdami paleisti dvejetainis vykdomąjį failą test01, kad buvo pagamintas rengimo (jei nebuvo klaidos), įveskite šį:

./test01

Kaskart keisti test01.cpp šaltinio kodo failą, jūs turite surinkti jį vėl, jei norite, kad pakeitimai būtų atsispindi test01 vykdomąjį failą (įrašykite rodyklės aukštyn klavišą klaviatūroje prisiminti komandas).

2.

Jūs galite naudoti // įvesti pastabą:

using namespace std;         // Using the standard library namespace.
#include <iostream> // The iostream library is often used.

int main () // The program's main routine.
{
double a; // Declaration of variable a.

a = 456.47;
a = a + a * 21.5 / 100; // A calculation.

cout << a << endl; // Display the content of a.

return 0; // Program end.
}



Output
554.611

(Galimybė naudoti // įvesti pastabas buvo įtraukta į C C99 ir ANSI C 2000)

3.

Įvesties iš klaviatūros ir išvesties į ekraną gali būti atliekamas per cout << ir cin >>:

using namespace std;
#include <iostream>

int main()
{
int a; // a is an integer variable
char s [100]; // s points to a string of max 99 characters

cout << "This is a sample program." << endl;

cout << endl; // Just a line feed (end of line)

cout << "Type your age : ";
cin >> a;

cout << "Type your name: ";
cin >> s;

cout << endl;

cout << "Hello " << s << " you're " << a << " old." << endl;
cout << endl << endl << "Bye!" << endl;

return 0;
}

Output
This is a sample program.

Type your age : 12
Type your name: Edmond       

Hello Edmond you're 12 old.


Bye!

4.

Kintamieji gali būti paskelbtas bet viduje kodas:

using namespace std;
#include <iostream>

int main ()
{
double a;

cout << "Hello, this is a test program." << endl;

cout << "Type parameter a: ";
cin >> a;

a = (a + 1) / 2;

double c;

c = a * 5 + 1;

cout << "c contains  : " << c << endl;

int i, j;

i = 0;
j = i + 1;

cout << "j contains  : " << j << endl;

return 0;
}


Output
Hello, this is a test program.
Type parameter a: 7
c contains      : 21
j contains      : 1

Gal pabandyti naudoti šią funkciją, kad jūsų kodo suprantamesnės, o ne netvarka jį.

Kaip ir C, kintamieji gali būti atitverti tarp { } blokus. Tada jie yra vietinio taikymo sritį į zoną aplieti tarp { ir }. Kad ir kas nutiktų su tokių kintamųjų viduje aplieti zonoje neturės įtakos zonai nepriklausančias:

using namespace std;
#include <iostream>

int main ()
{
double a;

cout << "Type a number: ";
cin >> a;

{
int a = 1;
a = a * 10 + 4;
cout << "Local number: " << a << endl;
}

cout << "You typed: " << a << endl;

return 0;
}


Output
Type a number: 9
Local number: 14
You typed: 9

5.

Kintamasis gali būti pradedamas skaičiavimu dalyvavo kitus kintamuosius:

using namespace std;
#include <iostream>

int main ()
{
double a = 12 * 3.25;
double b = a + 1.112;

cout << "a contains: " << a << endl;
cout << "b contains: " << b << endl;

a = a * 2 + b;

double c = a + b * a;

cout << "c contains: " << c << endl;

return 0;
}


Output
a contains: 39
b contains: 40.112
c contains: 4855.82

6.

C++ leidžia paskelbti kintamąjį būtų vietos į kilpą:

using namespace std;
#include <iostream>

int main ()
{
int i; // Simple declaration of i
i = 487;

for (int i = 0; i < 4; i++) // Local declaration of i
{
cout << i << endl; // This outputs 0, 1, 2 and 3
}

cout << i << endl; // This outputs 487

return 0;
}


Output
0
1
2
3
487

Jei kintamasis yra nedeklaravo kažkur virš kilpos, jums gali būti linkusios jį naudoti toliau kilpą. Kai kurie ankstyvi C++ kompiliatorius tai priimti. Tada kintamasis turi reikšmę tai turėjo kai kilpa baigėsi. Jūs ne tai turėtų daryti. Tai laikoma bloga praktika:

using namespace std;
#include <iostream>

int main ()
{

for (int i = 0; i < 4; i++)
{
cout << i << endl;
}

cout << i << endl; // Bad practice!
i += 5; // Bad practice!
cout << i << endl; // Bad practice!

return 0;
}


Gnu C++ compiler complain
t.cpp: In function ‘int main()’:
t.cpp:12: error: name lookup of ‘i’ changed for new ISO ‘for’ scoping
t.cpp:7: error:   using obsolete binding at ‘i’

7.

Pasaulinė kintamasis gali būti atvertas net jei kitas kintamasis tuo pačiu pavadinimu buvo paskelbtas viduje funkcijos:

using namespace std;
#include <iostream>

double a = 128;

int main ()
{
double a = 256;

cout << "Local a: " << a << endl;
cout << "Global a: " << ::a << endl;

return 0;
}


Output
Local a:  256
Global a: 128

8.

Ji yra įmanoma, kad vienas kintamasis būti dar vienas:

using namespace std;
#include <iostream>

int main ()
{
double a = 3.1415927;

double &b = a; // b is a

b = 89;

cout << "a contains: " << a << endl; // Displays 89.

return 0;
}

Output
a contains: 89

(Jei yra naudojamos rodyklės ir absoliučiai nori žinoti, kas atsitiks, tiesiog manau, kad double &b = a yra išverstas double *b = &a ir visus vėlesnius b pakeičiami *b.)

ETALONINIŲ b vertė negali būti pakeistas po jo deklaracijoje. Pavyzdžiui Jūs negalite rašyti, keletą eilučių toliau, &b = c tikintis, kad b yra dabar c. Jis negali dirbti. Viskas yra sakoma deklaracijoje eilutėje b. Nuoroda b ir kintamojo a yra susituokę ant tos linijos ir nieko juos atskirti.

Nuorodos gali būti naudojamas, kad būtų galima funkcija pakeisti skambinimo kintamąjį:

using namespace std;
#include <iostream>

void change (double &r, double s)
{
r = 100;
s = 200;
}

int main ()
{
double k, m;

k = 3;
m = 4;

change (k, m);

cout << k << ", " << m << endl; // Displays 100, 4.

return 0;
}


Output
100, 4

Jei yra naudojamos rodyklės C ir įdomu, kaip tiksliai virš darbų programa, čia yra kaip C++ kompiliatorius būtų išversti į C:

using namespace std;
#include <iostream>

void change (double *r, double s)
{
*r = 100;
s = 200;
}

int main ()
{
double k, m;

k = 3;
m = 4;

change (&k, m);

cout << k << ", " << m << endl; // Displays 100, 4.

return 0;
}


Output
100, 4

Nuoroda gali būti naudojama tegul funkcija grąžina kintamąjį:

using namespace std;
#include <iostream>

double &biggest (double &r, double &s)
{
if (r > s) return r;
else return s;
}

int main ()
{
double k = 3;
double m = 7;

cout << "k: " << k << endl; // Displays 3
cout << "m: " << m << endl; // Displays 7
cout << endl;

biggest (k, m) = 10;

cout << "k: " << k << endl; // Displays 3
cout << "m: " << m << endl; // Displays 10
cout << endl;

biggest (k, m) ++;

cout << "k: " << k << endl; // Displays 3
cout << "m: " << m << endl; // Displays 11
cout << endl;

return 0;
}


Output
k: 3
m: 7

k: 3
m: 10

k: 3
m: 11


Vėlgi, jei esate pripratę prie žymeklį aritmetiką ir jei jums įdomu, kaip aukščiau darbų programa, tiesiog įsivaizduokite, kad kompiliatorius išversti jį į šią standartinę C programą:

using namespace std;
#include <iostream>

double *biggest (double *r, double *s)
{
if (*r > *s) return r;
else return s;
}

int main ()
{
double k = 3;
double m = 7;

cout << "k: " << k << endl;
cout << "m: " << m << endl;
cout << endl;

(*(biggest (&k, &m))) = 10;

cout << "k: " << k << endl;
cout << "m: " << m << endl;
cout << endl;

(*(biggest (&k, &m))) ++;

cout << "k: " << k << endl;
cout << "m: " << m << endl;
cout << endl;

return 0;
}


Output
k: 3
m: 7

k: 3
m: 10

k: 3
m: 11


Norėdami baigti su, žmonėms, kurie turi susidoroti su rodyklėmis dar nepatinka, nuorodos Naudingos veiksmingai JT rodyklė kintamieji. Saugokitės tai galima laikyti bloga praktika, ir gali jums į bėdą. Žr http://web.archive.org/web/20131011080757/http://www.embedded.com/electronics-blogs/programming-pointers/4023307/References-vs-Pointers

using namespace std;
#include <iostream>

double *silly_function () // This function returns a pointer to a double
{
static double r = 342;
return &r;
}

int main ()
{
double *a;

a = silly_function();

double &b = *a; // Now b is the double towards which a points!

b += 1; // Great!
b = b * b; // No need to write *a everywhere!
b += 4;

cout << "Content of *a, b and r: " << b << endl;

return 0;
}


Output
Content of *a, b and r: 117653

9.

Vardų galima deklaruoti. Nurodytos per vardų kintamieji gali būti naudojamas dėka :: operatorius:

using namespace std;
#include <iostream>
#include <cmath>

namespace first
{
int a;
int b;
}

namespace second
{
double a;
double b;
}

int main ()
{
first::a = 2;
first::b = 5;

second::a = 6.453;
second::b = 4.1e4;

cout << first::a + second::a << endl;
cout << first::b + second::b << endl;

return 0;
}


Output
8.453
41005

10.

Jei funkcija yra tik paprastas eilutes kodo, nenaudoja for kilpomis ar panašiai, jis gali būti pripažintas Inline. Tai reiškia, jo kodas bus įterptas visur funkcija naudojama. Štai šiek tiek panašus į makro. Pagrindinis privalumas yra tai, programa bus greičiau. Mažas trūkumas yra tai, ji bus didesnis, nes buvo įterptas jai visur taikyti visą kodas funkcijos:

using namespace std;
#include <iostream>
#include <cmath>

inline double hypothenuse (double a, double b)
{
return sqrt (a * a + b * b);
}

int main ()
{
double k = 6, m = 9;

// Next two lines produce exactly the same code:

cout << hypothenuse (k, m) << endl;
cout << sqrt (k * k + m * m) << endl;

return 0;
}


Output
10.8167
10.8167

(Inline funkcijos buvo įtraukta į C C99 ir ANSI C 2000)

11.

Jūs žinote, klasikines kontrolės struktūras C: for, if, do, while, switch... C++ prideda dar viena valdymo struktūra, pavadintą EXCEPTION:

using namespace std;
#include <iostream>
#include <cmath>

int main ()
{
int a, b;

cout << "Type a number: ";
cin >> a;
cout << endl;

try
{
if (a > 100) throw 100;
if (a < 10) throw 10;
throw a / 3;
}
catch (int result)
{
cout << "Result is: " << result << endl;
b = result + 1;
}

cout << "b contains: " << b << endl;

cout << endl;

// another example of exception use:

char zero [] = "zero";
char pair [] = "pair";
char notprime [] = "not prime";
char prime [] = "prime";

try
{
if (a == 0) throw zero;
if ((a / 2) * 2 == a) throw pair;
for (int i = 3; i <= sqrt (a); i++)
{
if ((a / i) * i == a) throw notprime;
}
throw prime;
}
catch (char *conclusion)
{
cout << "The number you typed is "<< conclusion << endl;
}

cout << endl;

return 0;
}


Output
Type a number: 5

Result is: 10
b contains: 11

The number you typed is prime


12.

Ji yra įmanoma, kad nustatyti numatytuosius parametrus funkcijų:

using namespace std;
#include <iostream>

double test (double a, double b = 7)
{
return a - b;
}

int main ()
{
cout << test (14, 5) << endl; // Displays 14 - 5
cout << test (14) << endl; // Displays 14 - 7

return 0;
}


Output
9
7

13.

Vienas svarbus privalumas C++ yra FUNKCIJA PERKROVOS. Skirtingas funkcijas gali turėti tokį patį vardą, jei kažkas leidžia kompiliatorius juos atskirti: parametrų skaičiaus, tipo parametrų...

using namespace std;
#include <iostream>

double test (double a, double b)
{
return a + b;
}

int test (int a, int b)
{
return a - b;
}

int main ()
{
double m = 7, n = 4;
int k = 5, p = 3;

cout << test(m, n) << " , " << test(k, p) << endl;

return 0;
}


Output
11 , 2

14.

OPERATORIAUS PERKROVA gali būti naudojamas iš naujo apibrėžti pagrindinius simbolines operatorių naujų rūšių parametrų:

using namespace std;
#include <iostream>

struct vector
{
double x;
double y;
};

vector operator * (double a, vector b)
{
vector r;

r.x = a * b.x;
r.y = a * b.y;

return r;
}

int main ()
{
vector k, m; // No need to type "struct vector"

k.x = 2; // To be able to write
k.y = -1; // k = vector (2, -1)
// see chapter 19.

m = 3.1415927 * k; // Magic!

cout << "(" << m.x << ", " << m.y << ")" << endl;

return 0;
}


Output
(6.28319, -3.14159)

Be to daugyba, 43 kitų pagrindinių C++ operatoriai gali būti perkrautas, įskaitant + =, ++ masyvo [], ir tt...

<< Operatorius, paprastai naudojamas dvejetainis bėgius skaičiais, gali būti perkrautos duoti išėjimo į upelį, o ne (pvz, cout <<). Tai galima dar apkrauti << operatorių naujų duomenų tipų, kaip vektorių galia:

using namespace std;
#include <iostream>

struct vector
{
double x;
double y;
};

ostream& operator << (ostream& o, vector a)
{
o << "(" << a.x << ", " << a.y << ")";
return o;
}

int main ()
{
vector a;

a.x = 35;
a.y = 23;

cout << a << endl; // Displays (35, 23)

return 0;
}


Output
(35, 23)

15.

Pavargę apibrėžti tą pačią funkciją penkis kartus? Vienas apibrėžimas int tipo parametrų, vienas apibrėžimas double tipo parametrų, vienas apibrėžimas float tipo parametrų... Argi tu pamiršai vieną tipą? Ką daryti, jei nauja duomenų tipas naudojamas? Jokių problemų: C++ kompiliatorius gali automatiškai generuoti kiekvieną funkciją, kuri yra būtina versija! Tiesiog pasakyti, kaip ši funkcija atrodo deklaruojant template funkciją:

using namespace std;
#include <iostream>

template <class ttype>
ttype minimum (ttype a, ttype b)
{
ttype r;

r = a;
if (b < a) r = b;

return r;
}

int main ()
{
int i1, i2, i3;
i1 = 34;
i2 = 6;
i3 = minimum (i1, i2);
cout << "Most little: " << i3 << endl;

double d1, d2, d3;
d1 = 7.9;
d2 = 32.1;
d3 = minimum (d1, d2);
cout << "Most little: " << d3 << endl;

cout << "Most little: " << minimum (d3, 3.5) << endl;

return 0;
}


Output
Most little: 6
Most little: 7.9
Most little: 3.5

Ši funkcija minimalus naudojamas tris kartus aukščiau programą, tačiau C++ kompiliatorius generuoja tik dvi versijos IT: int minimum (int a, int b) ir double minimum (double a, double b). Tai daro už visos programos darbą.

Kas nutiktų, jei bandėte kažką panašaus apskaičiuojant minimum (i1, d1)? Kompiliatorius būtų pranešė, kad įvyko klaida. Tai todėl, kad šablonas teigiama, kad abu parametrai yra to paties tipo.

Jūs galite naudoti bet kokiam skirtingų šablonų duomenų tipų šabloną apibrėžimą. Ir ne visi parametrų tipai turi būti šablonai, kai kurie iš jų gali būti standartinių tipų ar vartotojo nustatytas (char, int, double...). Čia yra pavyzdys, kai minimum funkcija priima parametrus bet kokio tipo (skirtingų arba tas pats) ir išveda vertę, kuri turi pirmojo parametro tipas:

using namespace std;
#include <iostream>

template <class type1, class type2>
type1 minimum (type1 a, type2 b)
{
type1 r, b_converted;
r = a;
b_converted = (type1) b;
if (b_converted < a) r = b_converted;
return r;
}

int main ()
{
int i;
double d;

i = 45;
d = 7.41;

cout << "Most little: " << minimum (i, d) << endl;
cout << "Most little: " << minimum (d, i) << endl;
cout << "Most little: " << minimum ('A', i) << endl;

return 0;
}


Output
Most little: 7
Most little: 7.41
Most little: -

(ASCII kodas charakterio "-" yra 45, o "A" kodas yra 65.)

16.

Raktažodžiai new ir delete gali būti naudojamas paskirstyti ir deallocate atmintis. Jie yra švaresnis nei funkcijas malloc ir be standartinio C

new [] ir delete [] yra naudojamas matricos.

using namespace std;
#include <iostream>
#include <cstring>

int main ()
{
double *d; // d is a variable whose purpose
// is to contain the address of a
// zone where a double is located


d = new double; // new allocates a zone of memory
// large enough to contain a double
// and returns its address.
// That address is stored in d.

*d = 45.3; // The number 45.3 is stored
// inside the memory zone
// whose address is given by d.

cout << "Type a number: ";
cin >> *d;

*d = *d + 5;

cout << "Result: " << *d << endl;

delete d; // delete deallocates the
// zone of memory whose address
// is given by pointer d.
// Now we can no more use that zone.


d = new double[15]; // allocates a zone for an array
// of 15 doubles. Note each 15
// double will be constructed.
// This is pointless here but it
// is vital when using a data type
// that needs its constructor be
// used for each instance.

d[0] = 4456;
d[1] = d[0] + 567;

cout << "Content of d[1]: " << d[1] << endl;

delete [] d; // delete [] will deallocate the
// memory zone. Note each 15
// double will be destructed.
// This is pointless here but it
// is vital when using a data type
// that needs its destructor be
// used for each instance (the ~
// method). Using delete without
// the [] would deallocate the
// memory zone without destructing
// each of the 15 instances. That
// would cause memory leakage.

int n = 30;

d = new double[n]; // new can be used to allocate an
// array of random size.
for (int i = 0; i < n; i++)
{
d[i] = i;
}

delete [] d;


char *s;

s = new char[100];

strcpy (s, "Hello!");

cout << s << endl;

delete [] s;

return 0;
}


Output
Type a number: 6
Result: 11
Content of d[1]: 5023
Hello!

17.

Be standartinio C, struct yra tik duomenis. C++ A struct apibrėžimas taip pat gali būti nustatytas funkcijas. Tos funkcijos priklauso struct ir yra skirti veikti ant struct duomenis. Tos funkcijos yra vadinamos metodais. Pavyzdys žemiau apibrėžia metodo surface() dėl struct vector:

using namespace std;
#include <iostream>

struct vector
{
double x;
double y;

double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.x = 3;
a.y = 4;

cout << "The surface of a: " << a.surface() << endl;

return 0;
}


Output
The surface of a: 12

Aukščiau pavyzdžiui, a yra iš struct "vektorius" ATVEJIS. (Atkreipkite dėmesį, kad raktažodis "struct", deklaruojant vektorių a nebuvo būtina.)

Tiesiog kaip funkcija, metodas gali būti bet kokio C++ operatorius perkrovos, jokių parametrų skaičių (dar vienas parametras yra visada numanoma: egzempliorius jis veikia ant), grąžinti bet kokio parametro tipą, arba grąžinti ne parametrą ne visiems.

Kas yra class? Tai struct, kad išlaiko savo duomenis paslėptas. Tik gali prieiti prie duomenų, kad šios class metodus. Jūs negalite tiesiogiai prieiti prie duomenų, išskyrus atvejus, kai leidžiama pagal public: direktyva. Čia yra class apibrėžimo pavyzdys. Jis elgiasi lygiai taip pat, kaip aukščiau struct pavyzdžiui, nes klasės duomenis x ir y yra apibrėžiamas kaip visuomenės:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;

double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.x = 3;
a.y = 4;

cout << "The surface of a: " << a.surface() << endl;

return 0;
}


Output
The surface of a: 12

Aukščiau pateiktame pavyzdyje, main() funkcija keičia Pavyzdžiui duomenis a tiesiogiai, naudojant a.x = 3, a.y = 4. Tai tapo įmanoma public: direktyvą klasės apibrėžimą. Manoma, kad tai bloga praktika. Žiūrėkite 30 skyrių.

Metodas yra leidžiama pakeisti į atveju tai yra, veikiančią kintamuosius:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;

vector its_opposite()
{
vector r;

r.x = -x;
r.y = -y;

return r;
}

void be_opposited()
{
x = -x;
y = -y;
}

void be_calculated (double a, double b, double c, double d)
{
x = a - c;
y = b - d;
}

vector operator * (double a)
{
vector r;

r.x = x * a;
r.y = y * a;

return r;
}
};

int main ()
{
vector a, b;

a.x = 3;
a.y = 5;

b = a.its_opposite();

cout << "Vector a: " << a.x << ", " << a.y << endl;
cout << "Vector b: " << b.x << ", " << b.y << endl;

b.be_opposited();
cout << "Vector b: " << b.x << ", " << b.y << endl;

a.be_calculated (7, 8, 3, 2);
cout << "Vector a: " << a.x << ", " << a.y << endl;

a = b * 2;
cout << "Vector a: " << a.x << ", " << a.y << endl;

a = b.its_opposite() * 2;
cout << "Vector a: " << a.x << ", " << a.y << endl;

cout << "x of opposite of a: " << a.its_opposite().x << endl;

return 0;
}


Output
Vector a: 3, 5
Vector b: -3, -5
Vector b: 3, 5
Vector a: 4, 6
Vector a: 6, 10
Vector a: -6, -10
x of opposite of a: 6

18.

Labai ypatinga ir eteriniai metodai yra KONSTRUKTORIUS ir DESTRUKTORIUS. Jie automatiškai vadinama, kai tik A klasės egzempliorius yra sukurta ar sunaikinta (kintamasis deklaracija, pabaigos programą, new, delete...).

Konstruktorius bus inicijuoti į Pavyzdžiui kintamuosius, atlikti tam tikrus skaičiavimus, skirti už instancijos wypisuje teksto ... kokia reikalinga tam atmintį.

Čia yra klasės apibrėžimą su dviem perpildytą konstruktorių pavyzdys:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;

vector () // same name as class
{
x = 0;
y = 0;
}

vector (double a, double b)
{
x = a;
y = b;
}

};

int main ()
{
vector k; // vector () is called

cout << "vector k: " << k.x << ", " << k.y << endl << endl;

vector m (45, 2); // vector (double, double) is called

cout << "vector m: " << m.x << ", " << m.y << endl << endl;

k = vector (23, 2); // vector created, copied to k, then erased

cout << "vector k: " << k.x << ", " << k.y << endl << endl;

return 0;
}


Output
vector k: 0, 0

vector m: 45, 2

vector k: 23, 2


Tai gera praktika pabandyti neperkrauti konstruktoriai. Tai geriausia deklaruoti tik vienas konstruktorius ir mano, kad tai gamyklinių parametrų, kur tik įmanoma:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}
};

int main ()
{
vector k;
cout << "vector k: " << k.x << ", " << k.y << endl << endl;

vector m (45, 2);
cout << "vector m: " << m.x << ", " << m.y << endl << endl;

vector p (3);
cout << "vector p: " << p.x << ", " << p.y << endl << endl;

return 0;
}


Output
vector k: 0, 0

vector m: 45, 2

vector p: 3, 0


Destructor dažnai yra nereikalinga. Jūs galite naudoti ją padaryti kai skaičiavimus, kai egzempliorius sunaikinti arba išvesties kai tekstą derinti... Bet jei kintamieji pavyzdžiui punkto kai paskirta atminties tada destructor vaidmuo yra esminis: jis turi atlaisvinti tą atmintį! Čia yra tokios paraiškos pavyzdys:

using namespace std;
#include <iostream>
#include <cstring>

class person
{
public:

char *name;
int age;

person (char *n = "no name", int a = 0)
{
name = new char [100]; // better than malloc!
strcpy (name, n);
age = a;
cout << "Instance initialized, 100 bytes allocated" << endl;
}

~person () // The destructor
{
delete name; // instead of free!

// delete [] name would be more
// academic but it is not vital
// here since the array contains
// no C++ sub-objects that need
// to be deleted.

cout << "Instance going to be deleted, 100 bytes freed" << endl;
}
};

int main ()
{
cout << "Hello!" << endl << endl;

person a;
cout << a.name << ", age " << a.age << endl << endl;

person b ("John");
cout << b.name << ", age " << b.age << endl << endl;

b.age = 21;
cout << b.name << ", age " << b.age << endl << endl;

person c ("Miki", 45);
cout << c.name << ", age " << c.age << endl << endl;

cout << "Bye!" << endl << endl;

return 0;
}


Output
Hello!

Instance initialized, 100 bytes allocated
no name, age 0

Instance initialized, 100 bytes allocated
John, age 0

John, age 21

Instance initialized, 100 bytes allocated
Miki, age 45

Bye!

Instance going to be deleted, 100 bytes freed
Instance going to be deleted, 100 bytes freed
Instance going to be deleted, 100 bytes freed

Čia yra trumpas pavyzdys masyvo klasės apibrėžimą. Metodas, kuris yra iš [] operatoriaus perkrovos ir išėjimai nuorodą (&) yra naudojamas tam, kad generuoti klaidos, jei mėginama prieiti prie duomenų už masyvo ribų:

using namespace std;
#include <iostream>
#include <cstdlib>

class array
{
public:
int size;
double *data;

array (int s)
{
size = s;
data = new double [s];
}

~array ()
{
delete [] data;
}

double &operator [] (int i)
{
if (i < 0 || i >= size)
{
cerr << endl << "Out of bounds" << endl;
exit (EXIT_FAILURE);
}
else return data [i];
}
};

int main ()
{
array t (5);

t[0] = 45; // OK
t[4] = t[0] + 6; // OK
cout << t[4] << endl; // OK

t[10] = 7; // error!

return 0;
}


Output
51

Out of bounds

19.

Jei jums mesti objektą kaip vektorius, viskas įvyks teisingai. Pavyzdžiui, jei vektorius k kurio sudėtyje yra (4, 7), po to, kai lieto m = k vektorius m, yra (4, 7) taip pat Į k.x ir k.y vertybės tiesiog buvo nukopijuotas į m.x ir m.y. Dabar tarkime, kad žaidi su objektais, pavyzdžiui, person klasės aukščiau. Šie objektai yra rodyklė į simbolių eilutę. Jei jums mesti person objektą raštu p = r yra susigrąžintos, kad kai funkcija daro šį darbą padaryti p būti teisinga kopija r. Priešingu atveju, p.name nukreips į tą patį fizinį simbolių eilutę kaip r.name. Dar daugiau, buvusi simbolių atkreipė dėmesį į iki p.name yra prarasta ir tampa atminties Zombie. Rezultatas bus katastrofiška: iš rodyklės ir prarastų duomenų netvarka. Metodai, kurie bus atlikti darbą yra KOPIJA KONSTRUKTORIUI ir kad, = operatoriaus perkrovos:

using namespace std;
#include <iostream>
#include <cstring>

class person
{
public:

char *name;
int age;

person (char *n = "no name", int a = 0)
{
name = new char[100];
strcpy (name, n);
age = a;
}

person (const person &s) // The COPY CONSTRUCTOR
{
 name = new char[100];
  strcpy (name, s.name);
 age = s.age;
 }

person& operator= (const person &s) // overload of =
{
strcpy (name, s.name);
age = s.age;
return *this;
}

~person ()
{
delete [] name;
}
};

void modify_person (person& h)
{
h.age += 7;
}

person compute_person (person h)
{
h.age += 7;
return h;
}


int main ()
{
person p;
cout << p.name << ", age " << p.age << endl << endl;
// output: no name, age 0

person k ("John", 56);
cout << k.name << ", age " << k.age << endl << endl;
// output: John, age 56

p = k;
cout << p.name << ", age " << p.age << endl << endl;
// output: John, age 56

p = person ("Bob", 10);
cout << p.name << ", age " << p.age << endl << endl;
// output: Bob, age 10

// Neither the copy constructor nor the overload
// of = are needed for this operation that modifies
// p since just the reference towards p is passed to
// the function modify_person:
modify_person (p);
cout << p.name << ", age " << p.age << endl << endl;
// output: Bob, age 17

// The copy constructor is called to pass a complete
// copy of p to the function compute_person. The
// function uses that copy to make its computations
// then a copy of that modified copy is made to
// return the result. Finally the overload of = is
// called to paste that second copy inside k:
k = compute_person (p);
cout << p.name << ", age " << p.age << endl << endl;
// output: Bob, age 17
cout << k.name << ", age " << k.age << endl << endl;
// output: Bob, age 24

return 0;
}


Output
no name, age 0

John, age 56

John, age 56

Bob, age 10

Bob, age 17

Bob, age 17

Bob, age 24


Kopija konstruktorius leidžia savo programą kopijuoti atvejais, kai daro skaičiavimus. Ji yra pagrindinis metodas. Per skaičiavimais, atvejų yra sukurta, siekiant išlaikyti tarpinius rezultatus. Jie keisti, mesti ir sunaikinti be jūsų žinios. Tai kodėl šie metodai gali būti naudinga net paprastų objektų (žr 14 skyrių).

Be visų minėtų pavyzdžių, metodai yra apibrėžti klasės apibrėžimas viduje. Tai automatiškai daro juos Inline metodus.

20.

Jei metodas negali būti Inline arba nenorite, kad jis būtų Inline arba jei norite, kad klasės apibrėžimas yra minimalų kiekį informacijos (arba jūs tiesiog norite įprastą atskirą .h antraštės failą ir .cpp kodo failą) , tada jums reikia įdėti tik iš klasės viduje metodo prototipą ir apibrėžti žemiau klasės metodą (arba atskiroje .cpp šaltinio failo):

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;

double surface(); // The ; and no {} show it is a prototype
};

double vector::surface()
{
double s = 0;

for (double i = 0; i < x; i++)
{
s = s + y;
}

return s;
}

int main ()
{
vector k;

k.x = 4;
k.y = 5;

cout << "Surface: " << k.surface() << endl;

return 0;
}


Output
Surface: 20

Pradedantiesiems:

Jei ketinate kurti rimtą C ar C++ programą, jums reikia atskirti kodą į .h header files ir .cpp šaltinio failus. Tai yra trumpas pavyzdys, kaip tai daroma. Programa aukščiau yra padalyta į tris failus:

Antraštės failą vector.h:

class vector
{
public:

double x;
double y;

double surface();
};

Šaltinis failą vector.cpp:

using namespace std;
#include "vector.h"

double vector::surface()
{
double s = 0;

for (double i = 0; i < x; i++)
{
s = s + y;
}

return s;
}

Ir dar vienas šaltinio failas main.cpp:

using namespace std;
#include <iostream>
#include "vector.h"

int main ()
{
vector k;

k.x = 4;
k.y = 5;

cout << "Surface: " << k.surface() << endl;

return 0;
}

Darant prielaidą, kad vector.cpp yra tobulas, jums surinkti jį vieną kartą ir visiems laikams į .o "objektas failo". Toliau pateiktoje komanda gamina, kad objekto kodo failą, pavadintą vector.o:

g++ -c vector.cpp

Kaskart keisti main.cpp šaltinio failą, kaupia jį į vykdomąjį failą, tarkim test20. Jūs pasakykite kompiliatorius aiškiai nurodoma, kad jis turi susieti vector.o objekto failą į galutinį test20 vykdomąjį:

g++ main.cpp vector.o -o test20

Paleiskite vykdomąjį šį kelią:

./test20

Tai turi keletą privalumų:

  • Išeities kodas vector.cpp nereikia būti rengiami tik vieną kartą. Tai taupo laiką dėl didelių projektų daug. (Susiejimas vector.o failą į test20 vykdomąjį yra labai greitas.)
  • Galite somebody give .h failą ir .o failą(-s). Tokiu būdu jie gali naudoti savo programinę įrangą, bet ne jį pakeisti, nes jie neturi .cpp failą (-us) (nepasikliaukite per daug apie tai, palaukite kol meistras į šiuos klausimus).

Pastaba Jums gali sudaryti main.cpp per į objekto failą ir tada susieti jį su vector.o:

g++ -c main.cpp
g++ main.o vector.o test20

Tai nuklysta nuo "skirtumus tarp C ir C++" temą, bet jei norite atrodyti realus programuotojas, jums reikia kondensuoti pirmiau komandas į Makefile ir kaupia naudojant makiažo komandą. Failas turinys po yra pernelyg supaprastintu versija tokio Makefile. Nukopijuokite jį į failą pavadintą Makefile. Atkreipkite dėmesį, o tai yra labai svarbu, kad prieš g++ vadovaujamai erdvė yra privalomas ir kad tai yra "Tab" personažas. Negalima įveskite tarpo čia. Vietoj naudoti lentelių sudarymo raktą (visą kairę jūsų klaviatūros, virš didžiosios raidės).

test20: main.o vector.o
g++ main.o vector.o -o test20

main.o: main.cpp vector.h
g++ -c main.cpp

vector.o: vector.cpp vector.h
g++ -c vector.cpp

Kad naudoti kad Makefile kaupti, tipas:

make test20

Markę komanda bus apdoroti per failų Makefile ir išsiaiškinti, ką jis turi daryti. Norėdami pradėti su, tai sakė, kad test20 priklauso nuo main.o ir vector.o. Taigi bus automatiškai paleisti "make main.o", bei "make vector.o ". Tada jis patikrins, ar test20 jau egzistuoja ir tikrina datos antspaudai su test20, main.o ir  vector.o. Jei test20 jau egzistuoja ir main.o ir vector.o turėti data antspaudas anksčiau nei test20, make komanda nustato, kad dabartinė versija test20 yra atnaujinami, todėl neturi nieko. Jis tiesiog apie tai pranešti nieko. Priešingu atveju, jei neegzistuoja test20 arba main.o arba  vector.o yra naujesnis negu test20, komanda, kuri sukuria up-to-data versiją test20 atliekamas: g++ main.o vector.o -o test20.

Tai naujos versija Makefile yra arčiau į standartinį Makefile:

all: test20

test20: main.o vector.o
g++ main.o vector.o -o test20

main.o: main.cpp vector.h
g++ -c main.cpp

vector.o: vector.cpp vector.h
g++ -c vector.cpp

clean:
rm -f *.o test20 *~ #*

Jūs sukelti rengimo tiesiog įvesdami make komandą. Pirmoje eilutėje Makefile reiškia, kad jei jūs tiesiog įveskite make  jums skirtas "make test20":

make

Ši komanda ištrina visus failus gaminami rengimo metu ir visus teksto redaktorius atsarginių kopijų failus:

make clean

21.

Kai metodas yra taikoma bet kad, pavyzdžiui, metodas gali naudoti Pavyzdžiu kintamuosius, juos pakeisti... Bet kartais tai yra būtina žinoti Pavyzdžiui adresą. Ne problema, raktinis žodis tai yra skirti tam tikslui:

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double module()
{
return sqrt (x * x + y * y);
}

void set_length (double a = 1)
{
double length;

length = this->module();

x = x / length * a;
y = y / length * a;
}
};

int main ()
{
vector c (3, 5);

cout << "The module of vector c: " << c.module() << endl;

c.set_length(2); // Transforms c in a vector of size 2.

cout << "The module of vector c: " << c.module() << endl;

c.set_length(); // Transforms b in an unitary vector.

cout << "The module of vector c: " << c.module() << endl;

return 0;
}


Output
The module of vector c: 5.83095
The module of vector c: 2
The module of vector c: 1

22.

Žinoma, ji yra įmanoma pripažinti matricos objektų:

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double module ()
{
return sqrt (x * x + y * y);
}
};

int main ()
{
vector s [1000];

vector t[3] = {vector(4, 5), vector(5, 5), vector(2, 4)};

s[23] = t[2];

cout << t[0].module() << endl;

return 0;
}


Output
6.40312

23.

Čia yra pilna klasės deklaracijos pavyzdys:

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double = 0, double = 0);

vector operator + (vector);
vector operator - (vector);
vector operator - ();
vector operator * (double a);
double module();
void set_length (double = 1);
};

vector::vector (double a, double b)
{
x = a;
y = b;
}

vector vector::operator + (vector a)
{
return vector (x + a.x, y + a.y);
}

vector vector::operator - (vector a)
{
return vector (x - a.x, y - a.y);
}

vector vector::operator - ()
{
return vector (-x, -y);
}

vector vector::operator * (double a)
{
return vector (x * a, y * a);
}

double vector::module()
{
return sqrt (x * x + y * y);
}

void vector::set_length (double a)
{
double length = this->module();

x = x / length * a;
y = y / length * a;
}

ostream& operator << (ostream& o, vector a)
{
o << "(" << a.x << ", " << a.y << ")";
return o;
}

int main ()
{
vector a;
vector b;
vector c (3, 5);

a = c * 3;
a = b + c;
c = b - c + a + (b - a) * 7;
c = -c;

cout << "The module of vector c: " << c.module() << endl;

cout << "The content of vector a: " << a << endl;
cout << "The opposite of vector a: " << -a << endl;

c.set_length(2); // Transforms c in a vector of size 2.

a = vector (56, -3);
b = vector (7, c.y);

b.set_length(); // Transforms b in an unitary vector.

cout << "The content of vector b: " << b << endl;

double k;
k = vector(1, 1).module(); // k will contain 1.4142.
cout << "k contains: " << k << endl;

return 0;
}


Output
The module of vector c: 40.8167
The content of vector a: (3, 5)
The opposite of vector a: (-3, -5)
The content of vector b: (0.971275, 0.23796)
k contains: 1.41421

Ji yra taip pat galima apibrėžti funkciją gamina dviejų vektorių suma be paminėti jį vektoriaus klasės apibrėžimas viduje. Tada jis bus ne iš klasės vektorių metodu, o tiesiog funkcija, kuri naudoja vektorius:

vector operator + (vector a, vector b)
{
return vector (a.x + b.x, a.y + b.y);
}



Tuo atveju, kai visiškai klasės apibrėžimas Pavyzdžiui, kas išdėstyta, iš dvigubu vektoriaus daugyba apibrėžiama. Tarkime, mes norime dvigubos daugyba iš vektoriaus būti apibrėžtos taip pat. Tada mes turime parašyti izoliuotą funkciją lauko klasės:

vector operator * (double a, vector b)
{
return vector (a * b.x, a * b.y);
}



Žinoma, raktiniais new ir delete darbą klasės atvejais taip pat. Kas daugiau, new automatiškai iškviečia konstruktorius siekiant inicijuoti objektus ir delete automatiškai iškviečia destructor prieš deallocating atmintį instancijoje kintamieji imtis:

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double = 0, double = 0);

vector operator + (vector);
vector operator - (vector);
vector operator - ();
vector operator * (double);
double module();
void set_length (double = 1);
};

vector::vector (double a, double b)
{
x = a;
y = b;
}

vector vector::operator + (vector a)
{
return vector (x + a.x, y + a.y);
}

vector vector::operator - (vector a)
{
return vector (x - a.x, y - a.y);
}

vector vector::operator - ()
{
return vector (-x, -y);

}

vector vector::operator * (double a)
{
return vector (a * x, a * y);
}

double vector::module()
{
return sqrt (x * x + y * y);
}

void vector::set_length (double a)
{
vector &the_vector = *this;

double length = the_vector.module();

x = x / length * a;
y = y / length * a;
}

ostream& operator << (ostream& o, vector a)
{
o << "(" << a.x << ", " << a.y << ")";
return o;
}

int main ()
{
vector c (3, 5);

vector *r; // r is a pointer to a vector.

r = new vector; // new allocates the memory necessary
cout << *r << endl; // to hold a vectors' variable,
// calls the constructor who will
// initialize it to 0, 0. Then finally
// new returns the address of the vector.

r->x = 94;
r->y = 345;
cout << *r << endl;

*r = vector (94, 343);
cout << *r << endl;

*r = *r - c;
r->set_length(3);
cout << *r << endl;

*r = (-c * 3 + -*r * 4) * 5;
cout << *r << endl;

delete r; // Calls the vector destructor then
// frees the memory.

r = &c; // r points towards vector c
cout << *r << endl;

r = new vector (78, 345); // Creates a new vector.
cout << *r << endl; // The constructor will initialise
// the vector's x and y at 78 and 345

cout << "x component of r: " << r->x << endl;
cout << "x component of r: " << (*r).x << endl;

delete r;

r = new vector[4]; // creates an array of 4 vectors

r[3] = vector (4, 5);
cout << r[3].module() << endl;

delete [] r; // deletes the array

int n = 5;
r = new vector[n]; // Cute!

r[1] = vector (432, 3);
cout << r[1] << endl;

delete [] r;

return 0;
}


Output
(0, 0)
(94, 345)
(94, 343)
(0.77992, 2.89685)
(-60.5984, -132.937)
(3, 5)
(78, 345)
x component of r: 78
x component of r: 78
6.40312
(432, 3)

24.

Vienas ar daugiau kintamųjų klasė gali būti paskelbta static. Tokiu atveju, pateikiamas tik vieną kartą tų kintamųjų egzistuoja, kurią turi visi klasės atvejais. Ji turi būti pradedamas ne klasės deklaracijoje:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;
static int count;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
count++;
}

~vector()
{
count--;
}
};

int vector::count = 0;

int main ()
{
cout << "Number of vectors:" << endl;

vector a;
cout << vector::count << endl;

vector b;
cout << vector::count << endl;

vector *r, *u;

r = new vector;
cout << vector::count << endl;

u = new vector;
cout << a.count << endl;

delete r;
cout << vector::count << endl;

delete u;
cout << b.count << endl;

return 0;
}


Output
1
2
3
4
3
2

25.

Klasė a kintamasis taip pat gali būti pastovus. Štai kaip statinio, išskyrus ji teikiama vertę klasės deklaracijoje viduje ir ta vertė negali būti pakeistas:

using namespace std;
#include <iostream>

class vector
{
public:

double x;
double y;
const static double pi = 3.1415927;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double cylinder_volume ()
{
return x * x / 4 * pi * y;
}
};

int main()
{
cout << "The value of pi: " << vector::pi << endl << endl;

vector k (3, 4);

cout << "Result: " << k.cylinder_volume() << endl;

return 0;
}


Output
The value of pi: 3.14159

Result: 28.2743

26.

Klasė gali būti IŠSKIRTA iš kitos klasės. Nauja klasė PAVELDI kintamuosius ir metodus PAGRINDINĖS KLASĖS. Papildomų kintamųjų ir/ar metodai gali būti pridėta:

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double module()
{
return sqrt (x*x + y*y);
}

double surface()
{
return x * y;
}
};

class trivector: public vector // trivector is derived from vector
{
public:
double z; // added to x and y from vector

trivector (double m=0, double n=0, double p=0): vector (m, n)
{
z = p; // Vector constructor will
} // be called before trivector
// constructor, with parameters
// m and n.

trivector (vector a) // What to do if a vector is
{ // cast to a trivector
x = a.x;
y = a.y;
z = 0;
}

double module () // define module() for trivector
{
return sqrt (x*x + y*y + z*z);
}

double volume ()
{
return this->surface() * z; // or x * y * z
}
};

int main ()
{
vector a (4, 5);
trivector b (1, 2, 3);

cout << "a (4, 5) b (1, 2, 3) *r = b" << endl << endl;

cout << "Surface of a: " << a.surface() << endl;
cout << "Volume of b: " << b.volume() << endl;
cout << "Surface of base of b: " << b.surface() << endl;

cout << "Module of a: " << a.module() << endl;
cout << "Module of b: " << b.module() << endl;
cout << "Module of base of b: " << b.vector::module() << endl;

trivector k;
k = a; // thanks to trivector(vector) definition
// copy of x and y, k.z = 0
vector j;
j = b; // copy of x and y. b.z leaved out

vector *r;
r = &b;

cout << "Surface of r: " << r->surface() << endl;
cout << "Module of r: " << r->module() << endl;

return 0;
}


Output
a (4, 5)    b (1, 2, 3)    *r = b

Surface of a: 20
Volume of b: 6
Surface of base of b: 2
Module of a: 6.40312
Module of b: 3.74166
Module of base of b: 2.23607
Surface of r: 2
Module of r: 2.23607

27.

Virš programos, r->module() skaičiuoja vektoriaus modulį, naudojant x ir y, nes r buvo paskelbtas vektoriaus rodyklę. Tas faktas, kad r tikrųjų taškų į trivector Netiksli atsižvelgta. Jei norite, kad programa patikrinti smailiu objekto tipą ir pasirinkti tinkamą metodą, tada jūs privalo deklaruoti šį metodą kaip virtualus viduje pagrindinės klasės.

(Jei ne mažiau kaip vienas iš pagrindinės klasės metodų yra virtualus tada "antraštę" 4 baitų įtraukta į kiekvieną iš klasių pavyzdžiui. Tai leidžia programą, kad nustatytų, kas yra vektorius iš tikrųjų nurodo.) (4 baitų yra tikriausiai įgyvendinimas konkretus. Ant 64 bitų įrenginio gal tai yra 8 baitai...)

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

virtual double module()
{
return sqrt (x*x + y*y);
}
};

class trivector: public vector
{
public:
double z;

trivector (double m = 0, double n = 0, double p = 0)
{
x = m; // Just for the game,
y = n; // here I do not call the vector
z = p; // constructor and I make the
} // trivector constructor do the
// whole job. Same result.

double module ()
{
return sqrt (x*x + y*y + z*z);
}
};

void test (vector &k)
{
cout << "Test result: " << k.module() << endl;
}

int main ()
{
vector a (4, 5);
trivector b (1, 2, 3);

cout << "a (4, 5) b (1, 2, 3)" << endl << endl;

vector *r;

r = &a;
cout << "module of vector a: " << r->module() << endl;

r = &b;
cout << "module of trivector b: " << r->module() << endl;

test (a);

test (b);

vector &s = b;

cout << "module of trivector b: " << s.module() << endl;

return 0;
}


Output
a (4, 5)    b (1, 2, 3)

module of vector a: 6.40312
module of trivector b: 3.74166
Test result:          6.40312
Test result:          3.74166
module of trivector b: 3.74166

28.

Gal jums įdomu, jei klasė gali būti gaunami iš daugiau kaip vienos bazinės klasės. Atsakymas yra "taip":

using namespace std;
#include <iostream>
#include <cmath>

class vector
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double surface()
{
return fabs (x * y);
}
};

class number
{
public:

double z;

number (double a)
{
z = a;
}

int is_negative ()
{
if (z < 0) return 1;
else return 0;
}
};

class trivector: public vector, public number
{
public:

trivector(double a=0, double b=0, double c=0): vector(a,b), number(c)
{
} // The trivector constructor calls the vector
// constructor, then the number constructor,
// and in this example does nothing more.

double volume()
{
return fabs (x * y * z);
}
};

int main ()
{
trivector a(2, 3, -4);

cout << a.volume() << endl;
cout << a.surface() << endl;
cout << a.is_negative() << endl;

return 0;
}


Output
24
6
1

29.

Klasė išvedimas leidžia statyti daugiau sudėtingų klases pastatytas iš bazinių klasių. Yra ir kitas klasės išvedimą taikymas, leidžiantis programuotojas rašyti bendrosios funkcijos.

Tarkime, jūs apibrėžti pagrindinės klasės, be kintamųjų. Nėra jokios prasmės naudoti atvejus tos klasės viduje savo programą. Bet tada rašote funkciją, kurios tikslas yra rūšiuoti atvejų tos klasės. Kad funkcija bus rūšiuoti bet kurį iš objekto tipo, jeigu jis priklauso klasei, gautą iš pirmosios pagrindinės klasės gali! Vienintelė sąlyga yra ta, kad kiekvieno gauto klasės apibrėžimas vidų, visi metodai, kad rūšiavimo funkcija poreikiai teisingai apibrėžė:

using namespace std;
#include <iostream>
#include <cmath>

class octopus
{
public:

virtual double module() = 0; // = 0 implies function is not
// defined. This makes instances
// of this class cannot be declared.
};

double biggest_module (octopus &a, octopus &b, octopus &c)
{
double r = a.module();
if (b.module() > r) r = b.module();
if (c.module() > r) r = c.module();
return r;
}

class vector: public octopus
{
public:

double x;
double y;

vector (double a = 0, double b = 0)
{
x = a;
y = b;
}

double module()
{
return sqrt (x * x + y * y);
}
};

class number: public octopus
{
public:

double n;

number (double a = 0)
{
n = a;
}

double module()
{
if (n >= 0) return n;
else return -n;
}
};

int main ()
{
vector k (1,2), m (6,7), n (100, 0);
number p (5), q (-3), r (-150);

cout << biggest_module (k, m, n) << endl;
cout << biggest_module (p, q, r) << endl;

cout << biggest_module (p, q, n) << endl;

return 0;
}


Output
100
150
100

Galbūt manote, kad "gerai, kad yra gera idėja gauti klases nuo klasės octopus, nes aš, kad taip gali taikyti jį atvejais iš mano klasės metodų ir funkcijos, kurios buvo suprojektuotos bendriniu būdu octopus klasės. Bet kas, jei ten dar viena bazė klasė, pavadinta cuttlefish, kuri turi labai įdomių metodus ir funkcijas per daug? Ar aš turiu padaryti, kad mano pasirinkimą tarp octopus ir cuttlefish, kai aš noriu gauti klasę? " Ne zinoma ne. Išvestinė klasė gali būti gaunami iš abiejų octopus ir cuttlefish. Štai POLIMORFIZMAS. Gautoji klasė paprasčiausiai turi apibrėžti metodus, būtinus octopus kartu su metodais, kurie yra būtini cuttlefish:

class octopus
{
virtual double module() = 0;
};

class cuttlefish
{
virtual int test() = 0;
};

class vector: public octopus, public cuttlefish
{
double x;
double y;

double module ()
{
return sqrt (x * x + y * y);
}

int test ()
{
if (x > y) return 1;
else return 0;
}
}

30.

public: direktyva reiškia kintamuosius arba gali būti pasiekiamos, ir naudojamas visur programoje žemiau metodai.

Jei norite, kad kintamieji ir metodai būtų prieinami tik metodų klasę IR metodus, gautų klases, tada turite įdėti raktažodį protected: prieš juos.

Jei norite kintamieji arba metodai, prieinama TIK metodų klasės, tada turite įdėti raktažodį private: prieš juos.

Tas faktas, kad kintamieji arba metodai yra deklaruojamos privatus ar apsaugotas reiškia, kad nieko išorės į klasę galima pasiekti arba naudoti juos. Štai KAPSULIAVIMAS. (Jei norite suteikti specialią funkciją teisę susipažinti su tomis kintamuosius ir metodus, tada turite įtraukti šią funkciją prototipas klasės apibrėžties, prieš kurį raktažodžių friend viduje).

Gera praktika yra sutraukti visus klasės kintamuosius. Tai gali skambėti keistai, jei esate pripratę prie structs C tiesų struct prasmę tik jei galite prieiti prie savo duomenų... C++ jūs turite sukurti metodus acces duomenų viduje klasėje. Toliau pateiktas pavyzdys naudoja pagrindinę pavyzdį, klasifikuojamų 17 skirsnyje, dar pareiškia, kad klasė duomenys turi būti saugomi:

using namespace std;
#include <iostream>

class vector
{
protected:

double x;
double y;

public:

void set_x (int n)
{
x = n;
}
   void set_y (int n)
{
y = n;
}
double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.set_x (3);
a.set_y (4);

cout << "The surface of a: " << a.surface() << endl;

return 0;
}


Output
The surface of a: 12

Aukščiau pateiktame pavyzdyje yra šiek tiek keista, nes klasės duomenis X ir Y gali būti nustatytas, bet jie negali būti skaityti atgal. Bet funkcija main () bandymas skaityti a.x arba a.y rezultatas bus kompiliavimo klaida. Kitame pavyzdyje, X ir Y gali būti skaityti atgal:

using namespace std;
#include <iostream>

class vector
{
protected:

double x;
double y;

public:

void set_x (int n)
{
x = n;
}
   void set_y (int n)
{
y = n;
}

double get_x ()
{
return x;
}
   double get_y ()
{
return y;
}
double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.set_x (3);
a.set_y (4);

cout << "The surface of a: " << a.surface() << endl;
cout << "The width of a: " << a.get_x() << endl;
cout << "The height of a: " << a.get_y() << endl;

return 0;
}


Output
The surface of a: 12
The width of a:   3
The height of a:  4

C++ kalba vienas neturėtų prieiti prie duomenų iš klasės tiesiogiai. Metodai turi būti deklaruojamos. Kodėl tai? Daug priežasčių egzistuoti. Vienas yra tai, kad leidžia jums pakeisti būdą duomenys yra atstovaujama klasėje. Kita priežastis yra tai leidžia duomenų klasės viduje cross-priklausomi. Tarkime, x ir y visada turi būti to paties ženklo, kitaip negraži dalykai gali atsitikti... Jei vienas yra leidžiama pasiekti klasės duomenis tiesiogiai, būtų lengva nustatyti pasakyti teigiamus x ir neigiamą m. Žemiau pateiktame pavyzdyje tai yra griežtai kontroliuojamas:

using namespace std;
#include <iostream>

int sign (double n)
{
if (n >= 0) return 1;
return -1;
}

class vector
{
protected:

double x;
double y;

public:

void set_x (int n)
{
x = n;
if (sign (x) != sign(y)) y = -y;
}
   void set_y (int n)
{
y = n;
if (sign (y) != sign(x)) x = -x;
}

double get_x ()
{
return x;
}
   double get_y ()
{
return y;
}
double surface ()
{
double s;
s = x * y;
if (s < 0) s = -s;
return s;
}
};

int main ()
{
vector a;

a.set_x (-3);
a.set_y (4);

cout << "The surface of a: " << a.surface() << endl;
cout << "The width of a: " << a.get_x() << endl;
cout << "The height of a: " << a.get_y() << endl;

return 0;
}


Output
The surface of a: 12
The width of a:   3
The height of a:  4

31.

Pakalbėkime apie įvesties/išvesties. C++ kalba, kad tai labai plati tema.

Čia yra programa, kuri rašo į failą:

using namespace std;
#include <iostream>
#include <fstream>

int main ()
{
fstream f;

f.open("test.txt", ios::out);

f << "This is a text output to a file." << endl;

double a = 345;

f << "A number: " << a << endl;

f.close();

return 0;
}


Content of file test.txt
This is a text output to a file.
A number: 345

Čia yra programa, kuri skaito iš failo:



using namespace std;
#include <iostream>
#include <fstream>

int main ()
{
fstream f;
char c;

cout << "What's inside the test.txt file" << endl;
cout << endl;

f.open("test.txt", ios::in);

while (! f.eof() )
{
f.get(c); // Or c = f.get()
cout << c;
}

f.close();

return 0;
}


Output
This is a text output to a file.
A number: 345

32.

Apskritai, tai yra įmanoma padaryti simbolių masyvai tuos pačius veiksmus, kaip ant failų. Tai labai naudinga konvertuoti duomenis arba valdyti atminties masyvus.

Čia yra programa, kuri rašo viduje simbolių masyvas:

using namespace std;
#include <iostream>
#include <strstream>
#include <cstring>
#include <cmath>

int main ()
{
char a[1024];
ostrstream b(a, 1024);

b.seekp(0); // Start from first char.
b << "2 + 2 = " << 2 + 2 << ends; // ( ends, not endl )
// ends is simply the
// null character '\0'
cout << a << endl;

double v = 2;

strcpy (a, "A sinus: ");

b.seekp(strlen (a));
b << "sin (" << v << ") = " << sin(v) << ends;

cout << a << endl;

return 0;
}


Output
2 + 2 = 4
A sinus: sin (2) = 0.909297

Programa, kuri skaito iš simbolių eilutę:

using namespace std;
#include <iostream>
#include <strstream>
#include <cstring>

int main ()
{
char a[1024];
istrstream b(a, 1024);

strcpy (a, "45.656");

double k, p;

b.seekg(0); // Start from first character.
b >> k;

k = k + 1;

cout << k << endl;

strcpy (a, "444.23 56.89");

b.seekg(0);
b >> k >> p;

cout << k << ", " << p + 1 << endl;

return 0;
}


Output
46.656
444.23, 57.89

33.

Ši programa atlieka formato ir dviem skirtingais būdais. Atkreipkite dėmesį į width() ir setw() MODIFIKATORIAI yra veiksmingos tik kito elemento išėjimo į srautą. Vėlesni elementai nebus įtakos.

using namespace std;
#include <iostream>
#include <iomanip>

int main ()
{
int i;

cout << "A list of numbers:" << endl;
for (i = 1; i <= 1024; i *= 2)
{
cout.width (7);
cout << i << endl;
}

cout << "A table of numbers:" << endl;
for (i = 0; i <= 4; i++)
{
cout << setw(3) << i << setw(5) << i * i * i << endl;
}

return 0;
}


Output
A list of numbers:
      1
      2
      4
      8
     16
     32
     64
    128
    256
    512
   1024
A table of numbers:
  0    0
  1    1
  2    8
  3   27
  4   64

Dabar jūs turite pagrindinių žinių apie C++. Viduje gerų knygų jūs išmoksite daug daugiau dalykų. Failas valdymo sistema yra labai galingas, jis turi daug kitų galimybių, negu čia parodyta. Taip pat yra daug daugiau pasakyti apie klases: šablono klases, virtualiosios klasės...

Siekiant efektyviai dirbti su C++, jums reikės gera nuoroda knyga, kaip jums reikia vienas C. Taip pat reikia informacijos apie tai, kaip, C++ yra naudojami jūsų konkrečioje srityje veiklos. Standartai, pasaulio požiūris, gudrybės, tipiškas problemos ir jų sprendimai... Geriau

 

sias nuoroda yra žinoma knygos parašytos paties Bjarne Stroustrup (Nepamenu, kuris iš jų aš perskaičiau). Taip knyga yra beveik visos detales apie C ir C++, tai yra sukonstruotas tokiu būdu, panašiu į šį tekstą ir jame yra CD:

Jamsa's C/C++ Programmer's Bible
&copyright; 1998 Jamsa Press
Las Vegas, United States

Prancūzų kalba:
C/C++ La Bible du programmeur
Kris Jamsa, Ph.D - Lars Klander

France : Editions Eyrolles
www.eyrolles.com
Canada : Les Editions Reynald Goulet inc.
www.goulet.ca
ISBN 2-212-09058-7

Jis buvo prijungtas ir dabar:
Jamsa's C/C++/C# Programmer's Bible
Onword Press

Kita nuoroda:

accuwww.accu.org/bookreviews/public/reviews/0hr/index.htm

CoderSource.net:  www.codersource.net

C++ Guide:  google-styleguide.googlecode.com/svn/trunk/cppguide.xml

C++ Reference: fresh2refresh.com/c/c-language-history

 

Panaši pamoka Ada yra prieinama www.adahome.com/Ammo/cpp2ada.html

"Haskell pamoka pagal C programuotojas: learnyouahaskell.com

 

Noriu padėkoti Didier Bizzarri, Toni Ronkko, Frédéric Cloth, Jack Lam, Morten Brix Pedersen, Elmer Fittery, Ana Yuseepi, William L. Dye, Bahjat F. Qaqish, Muthukumar Veluswamy, Marco Cimarosti, Jarrod Miller, Nikolaos Pothitos, Ralph Wu, Dave Abercrombie, Alex Pennington, Scott Marsden, Robert Krten, Dave Panter, Cihat Imamoglu, Bohdan Zograf, David L. Markowitz, Marko Pozner, Filip Zaludek ir Kevin Wheeler jų įkvėpimo, patarimai, pagalba, duomenų, ataskaitos apie klaidas, nuorodos, stiprinimas anglų teksto ir vertimo.

Ericas Brasseur - Vasario 23 1998 iki Birželio 4 2014

Originalus anglų kalba http://www.4p8.com/eric.brasseur/cppcen.html