=====Problématique de base====== Soit une classe Y qui possède un membre de type classe X. L'objectif est que, si une méthode ''const'' de Y est appelée, il ne sera possible d'appeler que les méthodes ''const'' de X. Soit la classe commune ''X'' : #include struct X { void g() const { std::cout << "g (const)\n"; } void g() { std::cout << "g (non-const)\n"; } }; et le programme commun : int main() { Y y; y.f(); const Y cy; cy.f(); } ====Objet==== struct Y { Y() = default; void f() const { std::cout << "f (const)\n"; m_ptrX.g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX.g(); } X m_ptrX; }; Rendu : f (non-const) g (non-const) f (const) g (const) ====Pointeur==== struct Y { Y() : m_ptrX(new X()) {}; void f() const { std::cout << "f (const)\n"; m_ptrX->g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX->g(); } X* m_ptrX; }; Rendu : f (non-const) g (non-const) f (const) g (non-const) ====Référence==== struct Y { Y() : m_ptrX(m_X) {}; void f() const { std::cout << "f (const)\n"; m_ptrX.g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX.g(); } X& m_ptrX; X m_X; }; Rendu : f (non-const) g (non-const) f (const) g (non-const) =====propagate_const===== ====Pointeur==== Fonctionne avec ''X*'', ''std::unique_ptr'' et ''std::shared_ptr''. #include struct Y { Y() : m_ptrX(new X()) {}; void f() const { std::cout << "f (const)\n"; m_ptrX->g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX->g(); } std::experimental::propagate_const m_ptrX; }; Rendu : f (non-const) g (non-const) f (const) g (const) ====Référence==== Impossible. =====indirect_value===== ''indirect_value'' est un ''std::unique_ptr'' avec la préservation de ''const''. Il n'y a pas d'équivalent avec ''shared_ptr'' / ''pointeur'' / ''référence''. ====Pointeur==== #include struct Y { Y() : m_ptrX(isocpp_p1950::make_indirect_value()) {}; void f() const { std::cout << "f (const)\n"; m_ptrX->g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX->g(); } isocpp_p1950::indirect_value m_ptrX; }; Rendu : f (non-const) g (non-const) f (const) g (const) =====value_types===== ====Référence==== #include struct Y { Y() : m_ptrX(m_X) {}; void f() const { std::cout << "f (const)\n"; m_ptrX->g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX->g(); } xyz::indirect m_ptrX; X m_X; }; Rendu : f (non-const) g (non-const) f (const) g (const) ====Pointeur / allocation dynamique==== #include struct Y { Y() : m_ptrX(xyz::polymorphic()) {}; void f() const { std::cout << "f (const)\n"; m_ptrX->g(); } void f() { std::cout << "f (non-const)\n"; m_ptrX->g(); } xyz::polymorphic m_ptrX; }; Rendu : f (non-const) g (non-const) f (const) g (const)