En friend
Le mot-clé a un certain nombre de bons usages. Voici les deux utilisations qui me paraissent les plus évidentes :
Définition de l'ami
La définition amicale permet de définir une fonction dans la portée de la classe, mais la fonction ne sera pas définie comme une fonction membre, mais comme une fonction libre de l'espace de nom qui l'entoure, et ne sera pas visible normalement, sauf pour la recherche dépendante de l'argument. Cela le rend particulièrement utile pour la surcharge d'opérateurs :
namespace utils {
class f {
private:
typedef int int_type;
int_type value;
public:
// let's assume it doesn't only need .value, but some
// internal stuff.
friend f operator+(f const& a, f const& b) {
// name resolution finds names in class-scope.
// int_type is visible here.
return f(a.value + b.value);
}
int getValue() const { return value; }
};
}
int main() {
utils::f a, b;
std::cout << (a + b).getValue(); // valid
}
Classe de base privée CRTP
Parfois, on constate qu'une politique a besoin d'accéder à la classe dérivée :
// possible policy used for flexible-class.
template<typename Derived>
struct Policy {
void doSomething() {
// casting this to Derived* requires us to see that we are a
// base-class of Derived.
some_type const& t = static_cast<Derived*>(this)->getSomething();
}
};
// note, derived privately
template<template<typename> class SomePolicy>
struct FlexibleClass : private SomePolicy<FlexibleClass> {
// we derive privately, so the base-class wouldn't notice that,
// (even though it's the base itself!), so we need a friend declaration
// to make the base a friend of us.
friend class SomePolicy<FlexibleClass>;
void doStuff() {
// calls doSomething of the policy
this->doSomething();
}
// will return useful information
some_type getSomething();
};
Vous trouverez un exemple non-contourné pour cela dans este réponse. Un autre code utilisant cela se trouve dans este réponse. La base de la CRTP transfère son pointeur, afin de pouvoir accéder aux champs de données de la classe dérivée à l'aide de pointeurs de membres de données.