2016-02-12 159 views
4

我想創建一個簡單的3x3矩陣類並且能夠通過下標運算符訪問其內容。代碼如下:錯誤:從'const int *'無效轉換爲'int *'

// 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]; 
} 

我希望能夠訪問數組的元素,而不管矩陣的對象是const還是非const。但我從編譯器以下錯誤:

錯誤:從「const int的*」的無效轉換到「詮釋*」 [-fpermissive]

我做了一些研究,我有一個假設:也許,是因爲我已經把這個成員函數聲明爲一個const函數,在它的定義中,編譯器把所有對象的不可變成員都視爲const成員,所以這就是編譯器認爲它是從'const int *'改爲'int *'。 我的問題:這個假設是否正確?如果不是,那爲什麼會發生?我認爲這是有道理的,並且是確保'const Matrix * this'對象的一個​​好方法。

編譯器的信息: GCC 5.3.0從equation.com

+0

http://stackoverflow.com/questions/4059932/what-is-the-meaning-of-a-const-at-end-of-a-member-函數 –

回答

4

對於出現錯誤的原因,您是絕對正確的:在標記爲const的成員函數內,編譯器隱式地將該類的所有數據成員視爲使用const限定符聲明。

解決方法是真的簡單 - 可以覆蓋同一個運營商的兩倍,提供了const和非const版本:

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]; 
} 

編譯器會找出哪些超載基於呼叫上下文。如果Matrix本身爲const,則它將調用const版本,否則將調用const版本。

2
int* Matrix::operator[](const int index) const { 
    return this->matrix[index]; } 

在這裏,你說你不指定功能const修改對象的狀態下載。

但是,您正在返回一個指向您的實例變量的指針 - 並且通過該指針可以更改您的類的實例變量(以及狀態)的值。

因此,您可以創建該運算符的非常量版本以避免該問題。

3

當您聲明類方法(並且運算符是類方法)const時,這意味着您只能在類的字段上調用const方法,並且只返回const指針或對類字段的引用。爲了編譯,你需要讓你的心有兩種:

const int* Matrix::operator[](const int index) const { return this->matrix[index]; } 

int* Matrix::operator[](const int index) { return this->matrix[index]; } 

或兩者兼而有之。

+0

不知道const函數的返回限制,謝謝!但我期待着有關編譯器行爲的一些答案。正如dasblinkenlight所說,我可以兼具兩種功能! = D – Arnaldium

0

由於您從const member function(或operator)返回pointer,所以出現此錯誤。

const member functionoperator不應該更改任何non-mutable成員既不返回pointers可以稍後更改它們。

讓你的操作符返回const指針而不是指針。

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]; 
} 

Live Demo

0

更改此:

int* Matrix::operator[](const int index) const 

這個

const int* Matrix::operator[](const int index) const 

不能從const函數指針的可變返回數據成員。

或者您可以創建操作的兩個版本:常量和非const的:

const int* Matrix::operator[](const int index) const; 
int* Matrix::operator[](const int index); 

PS。無論如何,返回指向內部類成員的指針或引用是一種非常糟糕的做法。

+0

我想能夠訪問矩陣成員就好像它是一個二維數組(例如:Matrix m; m [2] [1] = 7.5;),並且還能夠使用其他矩陣操作操作員超載(例如:矩陣m1,m2; m1 + = m2; m2 * = m1)。所以這就是爲什麼我使用一個類的原因,'int matrix [3] [3]'成員是私有的原因只是爲了隱藏實現。我想沒有其他方式像m [2] [1](下標操作符兩次)使用對象而不返回指針,實際上我沒有看到這樣做的問題。 =) – Arnaldium

0

希望這有助於:

#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; 
}