问题
I'm having trouble with overloading operator() with a const version:
#include <iostream>
#include <vector>
using namespace std;
class Matrix {
public:
Matrix(int m, int n) {
vector<double> tmp(m, 0.0);
data.resize(n, tmp);
}
~Matrix() { }
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<double> > data;
};
int main() {
try {
Matrix 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; }
}
This gives me the following output:
- NONconst-version was called - - NONconst-version was called - A(1,1)=8.8
- NONconst-version was called - Error: you may only alter the first row of the matrix.
How can I achieve that C++ call the const-version of operator()? I am using GCC 4.4.0.
回答1:
The overloading looks fine but you never call it on a const object. You can try this:
void foo(const Matrix& A) {
cout << "A(1,1)=" << A(1,1) << endl;
}
Matrix A(10,10);
foo(A);
This gives you:
- const-version was called - A(1,1)=0
回答2:
The object you are calling the method on must be const, e.g.
cout << "A(2,2)=" << (*static_cast<const Matrix*>(&A))(2,2) << endl;
回答3:
Generally, you can't call a const or non-const version of a function depending on what you do with the return value. If you want to emulate similar functionality, you can try returning some proxy that will switch the behaviour depending on what you do with it:
class Proxy
{
Matrix& 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 Matrix::operator(int x, int y)
{
return Proxy(*this, x, y);
}
Assuming check()
is your check for legal mutation (could be integrated in index()
) and index()
and const_index()
are methods in Matrix that give a reference or const reference to a particular place.
回答4:
Use const_cast<>() or make your instance const.
I'm guessing maybe you want to be sure the operator returns a const double? Maybe you should just provide the const version, not the other one.
回答5:
You have different methods with different functionality, so give them different names. Then you don't need to have a const
object just to call what you want.
You can still make operator() const
call the alternative function in case you do happen have a const object. But the alternative functionality should be put in a function with a descriptive name.
As for getting a const
handle to an object, use static_cast< const Matrix & >( A )
.
来源:https://stackoverflow.com/questions/2440691/const-operator-overloading-problems-in-c