=====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)