Const operator overloading problems in C++

╄→гoц情女王★ 提交于 2019-12-12 16:19:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!