Reputation: 111
I want to create a simple 3x3 matrix class and be able to access its contents by the subscript operator. Here's the code:
// Matrix.h
class Matrix {
private:
int matrix[3][3];
public:
int* operator[](const int index) const;
};
// Matrix.cpp
int* Matrix::operator[](const int index) const {
return this->matrix[index];
}
I want to be able to access the elements of the array no matter whether the Matrix's object is const or non-const. But I get the following error from the compiler:
error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
I did some research and I have a hypothesis: maybe, because I have declared this member function as a const function, inside its definition the compiler treats (it masks) all of the the object's non-mutable members as const members, so that would be the reason the compiler says it's an invalid conversion from 'const int*' to 'int*'. My question: Is this hypothesis correct? And if it's not, why does that happens? I think it makes sense and would be a great way of ensuring the const-ness of the 'const Matrix *this' object.
Compiler Info: gcc 5.3.0 downloaded from equation.com
Upvotes: 4
Views: 4970
Reputation: 65
hope this helps:
#include<iostream>
using namespace std;
class Matrix
{
private:
int matrix[3][3];
public:
const int* operator[](const int index) const;
Matrix(int* value); // need an initializer though :)
};
const int* Matrix::operator[](const int index) const
{
return this->matrix[index];
}
Matrix::Matrix(int* value)
{
for(int i=0; i<3;i++)
{
for (int j=0; j<3; j++)
{
matrix[i][j]= *value;
value++;
}
}
}
int main( void )
{
int arr[] = {1,2,3,4,5,6,7,8,9};
Matrix C(arr);
const int *c;
c = C[0];
for(int i=0;i<3;i++)
{
cout << *c << ends;
c++;
}
return 0;
}
Upvotes: 0
Reputation: 8401
Change this:
int* Matrix::operator[](const int index) const
to this
const int* Matrix::operator[](const int index) const
You cannot return mutable pointer to data member from const function.
Or you may create two versions of operator: const and non const:
const int* Matrix::operator[](const int index) const;
int* Matrix::operator[](const int index);
PS. And anyway it's a very bad practice to return pointer or reference to internal class members.
Upvotes: 0
Reputation: 20264
You are getting this error because you are return a pointer
from a const member function
(or operator
).
const member function
and operator
should not change any non-mutable
member neither return pointers
that can change them later.
Make your operator return const pointer rather than pointer.
class Matrix {
private:
int matrix[3][3];
public:
int const* operator[](const int index) const;
};
// Matrix.cpp
int const* Matrix::operator[](const int index) const {
return this->matrix[index];
}
Upvotes: 0
Reputation: 726579
You are absolutely right about the reason why you get the error: inside a member function marked const
the compiler implicitly treats all data members of the class as if they were declared with a const
qualifier.
The fix is really straightforward - you can override the same operator twice, providing a const
and a non-const
versions:
class Matrix {
private:
int matrix[3][3];
public:
const int* operator[](const int index) const;
int* operator[](const int index);
};
// Matrix.cpp
const int* Matrix::operator[](const int index) const {
return this->matrix[index];
}
int* Matrix::operator[](const int index) {
return this->matrix[index];
}
The compiler will figure out which overload to call based on the context. It will call const
version if the Matrix
itself is const
, and the non-const
version otherwise.
Upvotes: 4
Reputation: 8874
When you declare a class method (and operator is a class method) const
, that means you can only call const
methods on your class's fields and return only const
pointers or references to class fields. In order to compile, you need to make up your mind to have either:
const int* Matrix::operator[](const int index) const { return this->matrix[index]; }
or
int* Matrix::operator[](const int index) { return this->matrix[index]; }
or both.
Upvotes: 3
Reputation: 28654
int* Matrix::operator[](const int index) const {
return this->matrix[index]; }
Here you say you don't modify the state of your object by specifying function as const
.
But you are returning a pointer to your instance variable - and through that pointer it is possible to change value of the instance variable of your class (and thus the state).
So you can create a non const version of that operator to avoid that issue.
Upvotes: 2