Les réponses précédentes sont parfaitement valables. Je veux juste ajouter une motivation potentielle pour laquelle il peut parfois être utile de retourner des objets const. Dans l'exemple suivant, class A
donne un aperçu des données internes de class C
, qui dans certains cas ne doivent pas être modifiables (Avertissement: par souci de brièveté, certaines parties essentielles sont omises - également dans ce cas sont probablement des moyens plus faciles pour implémenter ce comportement):
class A {
int *data;
friend class C; // allow C to call private constructor
A(int* x) : data(x) {}
static int* clone(int*) {
return 0; /* should actually clone data, with reference counting, etc */
}
public:
// copy constructor of A clones the data
A(const A& other) : data(clone(other.data)) {}
// accessor operators:
const int& operator[](int idx) const { return data[idx]; }
// allows modifying data
int& operator[](int idx) { return data[idx]; }
};
class C {
int* internal_data;
public:
C() : internal_data(new int[4]) {} // actually, requires proper implementation of destructor, copy-constructor and operator=
// Making A const prohibits callers of this method to modify internal data of C:
const A getData() const { return A(internal_data); }
// returning a non-const A allows modifying internal data:
A getData() { return A(internal_data); }
};
int main()
{
C c1;
const C c2;
c1.getData()[0] = 1; // ok, modifies value in c1
int x = c2.getData()[0]; // ok, reads value from c2
// c2.getData()[0] = 2; // fails, tries to modify data from c2
A a = c2.getData(); // ok, calls copy constructor of A
a[0] = 2; // ok, works on a copy of c2's data
}