Problèmes de surcharge de l’opérateur Const en C ++

J’ai des problèmes avec la surcharge de operator () avec une version constante:

#include  #include  using namespace std; class Masortingx { public: Masortingx(int m, int n) { vector tmp(m, 0.0); data.resize(n, tmp); } ~Masortingx() { } const double & operator()(int ii, int jj) const { cout << " - const-version was called - "; return data[ii][jj]; } double & operator()(int ii, int jj) { cout << " - NONconst-version was called - "; if (ii!=1) { throw "Error: you may only alter the first row of the matrix."; } return data[ii][jj]; } protected: vector< vector > data; }; int main() { try { Masortingx A(10,10); A(1,1) = 8.8; cout << "A(1,1)=" << A(1,1) << endl; cout << "A(2,2)=" << A(2,2) << endl; double tmp = A(3,3); } catch (const char* c) { cout << c << endl; } } 

Cela me donne la sortie suivante:

  • NONconst-version s’appelait – – NON NON config-version s’appelait – A (1,1) = 8,8
  • NONconst-version a été appelée – Erreur: vous ne pouvez modifier que la première ligne de la masortingce.

Comment puis-je obtenir que C ++ appelle la version constante de operator ()? J’utilise GCC 4.4.0.

La surcharge semble correcte mais vous ne l’appelez jamais sur un object const. Vous pouvez essayer ceci:

 void foo(const Masortingx& A) { cout << "A(1,1)=" << A(1,1) << endl; } Matrix A(10,10); foo(A); 

Cela vous donne:

  - const-version was called - A(1,1)=0 

L’object sur lequel vous appelez la méthode doit être const, par exemple

 cout << "A(2,2)=" << (*static_cast(&A))(2,2) << endl; 

En règle générale, vous ne pouvez pas appeler une version const ou non-const d’une fonction en fonction de ce que vous faites avec la valeur de retour. Si vous souhaitez émuler des fonctionnalités similaires, vous pouvez essayer de renvoyer un proxy qui changera le comportement en fonction de ce que vous en ferez:

 class Proxy { Masortingx& m; int x, y; public: ... // mutating operations operator double&() { check(); return m.index(x,y); } double& operator=(double d) { check(); return m.index(x,y)=d; } // ... other mutating operations (+=, ...) analogously // nonmutating ops operator double() { return m.const_index(x, y); } operator const double&() // ... same }; Proxy Masortingx::operator(int x, int y) { return Proxy(*this, x, y); } 

En supposant que check() soit votre contrôle de mutation légale (pourrait être intégré dans index() ) et index() et const_index() sont des méthodes dans Masortingx qui donnent une référence ou une référence const à un endroit particulier.

Utilisez const_cast <> () ou faites votre instance const.

J’imagine que vous voulez peut-être être sûr que l’opérateur retourne un const double? Peut-être devriez-vous simplement fournir la version const, pas l’autre.

Vous avez différentes méthodes avec des fonctionnalités différentes, donc donnez-leur des noms différents. Dans ce cas, vous n’avez pas besoin d’un object const pour appeler ce que vous voulez.

Vous pouvez toujours faire en sorte que operator() const appelle la fonction alternative au cas où vous auriez un object const. Mais la fonctionnalité alternative devrait être mise dans une fonction avec un nom descriptif.

Pour obtenir un handle const à un object, utilisez static_cast< const Matrix & >( A ) .