-->
La relation d'amitié est à utiliser avec autant de
parcimonie et de précaution que le goto !!!
Fonction amie |
class compte { |
friend void print(const compte&); |
public : |
... |
}; |
void print(const compte& c) { |
cout << c.nom_proprio << ":" ; |
cout << c.solde << endl; |
} |
// Exemple fictif à ne pas suivre : |
// Ici, print() devrait être membre |
// de la classe compte... |
Classe amie (1) |
class Banque ; // déclaration anticipée |
class compte { |
friend class Banque ; |
... |
}; |
class Banque { |
... |
}; |
Classe amie (2) |
class compte { |
friend void Banque::fraisgestion(compte&, int) ; |
... |
}; |
class Banque { |
public: |
void fraisgestion(compte&, int) ; |
... |
}; |
void Banque::fraisgestion(compte& c,int val) |
{ |
c.solde -= val; // accès à la donnée privée ``solde'' |
} |
Fonction membre constante (1) |
Fonction membre constante (2) |
class compteur { |
int valeur ; |
public : |
compteur(int v=0) {valeur = v ;} |
int get(void) const { return valeur; }; |
int badget(void) { return valeur; } |
int worseget(void) const; |
void set(int v) { valeur = v; } |
}; |
int compteur::worseget(void) const { |
set(5); // Erreur de compil. ! |
return valeur; |
} |
int main(void) { |
int i; compteur c1; const compteur c2(10); |
c2.set(1) ; // Erreur : c2 constant |
c1.set(1) ; // OK |
c2.get() ; // OK |
c2.badget(); // Erreur de compil. ! |
} |
Fonction membre expansée |
class compte { | |
int solde ; | |
... | |
public : | |
int getSolde(void) const { // déf. expansée | |
return solde ; } | |
void retirer(int montant); | |
... | |
}; | |
inline void compte::retirer(int montant) | |
{ solde -= montant ; } |
Donnée membre statique |
class compte { ... |
static int nextNumero ; |
int numero; ... |
}; |
compte::compte(char * nom) { |
numero = (nextNumero++); ... |
} |
int compte::nextNumero = 1 ; // initialisation |
Fonction membre statique (1) |
Fonction membre statique (2) |
class compte { |
static int nextNumero ; |
... |
public : |
static void setNext(int x) ; |
... |
}; |
static void compte::setNext(int x) { |
nextNumero = x ; |
} |
int compte::nextNumero = 0; |
// ... |
compte::setNext(100); // OK car publique |
Exemple : compte.h |
#ifndef COMPTE_H | ||
#define COMPTE_H | ||
#include "String.h" | ||
class compte { | ||
public : | ||
compte(const String& nom); | ||
~ compte() ; |
||
int getSolde(void) const ; | ||
String proprio(void) const { | ||
return nom_proprio ; } | ||
void deposer(int som) ; | ||
void retirer(int som) ; | ||
private : | ||
int solde ; | ||
const String& nom_proprio ; | ||
const int numero ; | ||
static int nextNumero; | ||
static int nbComptes; | ||
} ; | ||
#endif |
Exemple : compte.cpp |
#include "compte.h" | |
compte::nextNumero = 1; | |
compte::nbComptes = 0; | |
compte::compte(const string& nom) : solde(0), | |
nom_proprio(nom), numero(nextNumero++) | |
{ | nbComptes++ ; } |
compte::~ compte() { nbComptes--; } |
|
inline int compte::getSolde(void) const | |
{ return solde ; } | |
void compte::deposer(int som) | |
{ solde += som; } | |
void compte::retirer(int som) | |
{ solde -= som ; } |
int compte::method(...) { |
// solde == this-> solde |
compte tmp = *this; |
... |
} |
Pointeur sur fonction membre |
// ptMet est un pointeur vers une méthode |
// de la classe String |
Pointeur sur donnée membre |
// pt est un pointeur vers attribut |
// de type int de la classe compte |
class Table; // déclaration anticipée |
typedef void (Table::* PtMet) (unsigned); |
class Table { |
public: |
Table(unsigned, unsigned); |
void up(unsigned n = 1) ; |
void down(unsigned n = 1) ; |
void left(unsigned n = 1) ; |
void right(unsigned n = 1) ; |
void move(int, PtMet, int, PtMet); |
private: |
unsigned int x,y; // }; |
void Table::move(int m, PtMet h, int n, PtMet l) { |
(this->*h)(m); (this->*l)(n); } |
void func2(unsigned) ; |
void (* ptf) (unsigned) ; |
void (Table::*ptfc) (unsigned) ; |
ptf = &func2; // ok |
ptf = &Table::up; // Erreur |
ptfc = &func2; // Erreur |
ptfc = &Table::up; // ok |
Table b(1,1); |
b.*ptfc(1); |
b.move(1,&Table::up,1,&Table::left) ; |
Pointeur sur fonction membre statique |
class Foo { |
public: |
static int sfunc (void) ; |
int nsfunc (void) ; |
}; |
int (*ptsfunc) (void); |
int (Foo::*ptnsfunc) (void); |
ptsfunc = &Foo::sfunc; // ok |
ptsfunc = &Foo::nsfunc; // Erreur |
ptnsfunc = &Foo::sfunc; // Erreur |
ptnsfunc = &Foo::nsfunc; // ok |
classX::classX(const classX&); |
Constructeur par recopie (2) |
class String { | |
private: | |
int len ; char * pt ; | |
public: | |
String(char *st) { | |
len = strlen(st); | |
pt = new char[len+1]; | |
strcpy(pt, st); | |
} | |
}; | |
String s1("toto"); // º s1="toto"; | |
String s2 = s1; // º s2(s1); | |
// recopie bit à bit | |
// Þ s1 et s2 partagent le même pointeur! |
String::String(const String& s) : len(s.len) { |
pt = new char[len+1]; // alloc. nouv. espace |
strcpy(pt,s.pt); // recopie |
} |
Constructeurs et conversion de type |
class bigint { |
... |
public : |
bigint(int); // Constr. 1 |
bigint(const char *); // Constr. 2 |
... |
}; |
int main(void) |
{ |
bigint a = 546734567; // Constr. 1 |
bigint b = "789065433"; // Constr. 2 |
// º b("789065433"); |
a = "90"; // Constr. 2 |
... // + affectation (cf. plus loin) |
} |
Passage d'arguments |
void essai(compte p); |
void essai(compte& p); |
void essai(const compte& p); |
Résultats d'une fonction membre |
class Point { | |
int x,y; | |
public: | |
Point& setX(int v) { | |
x=v; return *this; } | |
Point& setY(int v) { | |
y=v; return *this; } | |
}; | |
int main() { | |
Point p; | |
(p.setX(4)).setY(2); | |
} |