2016-09-21 2 views
0

Impossible d'accéder à un tableau 2D que j'ai créé dans le constructeur dans la fonction de classe printMatrix. Quand j'appelle la fonction en main avec une cout < < "test" simple; ça va imprimer ça. Si j'essaie d'imprimer les valeurs de matrixArray [] [], il n'imprime rien et quitte le programme. Est-ce que je ne fais pas référence au tableau 2d correctement?Référencement d'un tableau 2d dans une fonction de classe en C++

class matrix 
{ 
    int **matrixArray; 

public: 
    int matrixSize = 0; 
    matrix(int matrixSize); 
    void printMatrix(); 
    void makeMagicSquare(); 
}; 
matrix::matrix(int const matrixSize) 
{ 
    this->matrixSize = matrixSize ; 


    int** matrixArray = new int*[matrixSize]; 
     for(int i = 0; i<matrixSize; i++){ 
      matrixArray[i] = new int[matrixSize]; 
     } 


    for(int row = 0; row < matrixSize ;row++) 
      { 
       for(int col = 0; col < matrixSize; col++) 
       { 
        matrixArray[row][col] =0; 
        cout << matrixArray[row][col] << " "; 
       }//End for Col 
       cout << endl; 
      }//End for Row 

} 
//printMatrix Function 
void matrix::printMatrix(){ 

for(int row = 0; row < matrixSize;row++) 
     { 
      for(int col = 0; col < matrixSize; col++) 
      { 
       cout << "test" << " "; 
       //Not able to print from print function 
       cout << matrixArray[row][col] << endl; 
      }// end col 
      cout << endl; 
     }//end row 

} 
+0

Vous devriez vraiment stocker la matrice dans un vecteur unidimensionnel. – NathanOliver

+0

quelqu'un va-t-il vous claquer si vous utilisez 'vector >' à la place? –

+0

@ Jean-FrançoisFabre Seulement quelqu'un qui se soucie beaucoup de la localisation du cache. Les vecteurs 1D sont meilleurs. – vsoftco

Répondre

4

Comment pourriez-vous?

int** matrixArray = new int*[matrixSize]; 

est une variable locale dans le constructeur, ainsi matrixArray n'est visible à l'intérieur du constructeur.

Utilisez le membre de données au lieu et vous serez bien, et puisque vous avez déjà défini ce membre, vous devez simplement faire:

matrixArray = new int*[matrixSize]; 

Ne pas oublier de supprimer votre mémoire dans le destructor! ;)

+1

En fait, OP doit juste enlever 'int **'. Bonne prise! – vsoftco

+0

Merci @vsoftco, j'ai mis à jour ma réponse pour la rendre claire pour tout le monde! ;) – gsamaras

+0

et n'oubliez pas de créer un constructeur de copie et un opérateur d'affectation qui ne copie pas simplement la valeur du pointeur mais duplique les données, sans fuites de mémoire. Bonne chance, ce n'est pas si facile. –

1

Vous avez fait une erreur très courante, en omettant de faire la distinction entre les variables/paramètres locaux et les variables membres.

int** matrixArray = new int*[matrixSize]; 

Parce que cette expression commence par un type, il est une déclaration d'une nouvelle variable locale, qui est « cacher » le membre de classe (vous auriez à utiliser this->matrixArray pour y accéder, et il serait ne pas être initialisé). Votre compilateur devrait vous donner un avertissement de "variable d'ombre".

Une pratique courante consiste à donner des variables membres un distingueur: certains les préfixe "m_", certains mettent un trailing "_", de sorte que votre code deviendrait:

class matrix 
{ 
    int **matrixArray_ = nullptr; //1 
    int matrixSize_ = 0; //2 

public: 
    matrix(int matrixSize); 
    ~matrix(); //7 
    void printMatrix() const; 
    void makeMagicSquare(); 
    int size() const { return matrixSize_; } //3 
}; 

matrix::matrix(int const matrixSize) 
    : matrixSize_(matrixSize) //4 
{ 
    matrixArray_ = new int*[matrixSize_]; //5 
    for(int i = 0; i<matrixSize_; i++) { 
     matrixArray_[i] = new int[matrixSize_](); //6 
    } 
} 

matrix::~matrix() //7 
{ 
    if (!_matrixArray) 
     return; 
    for (int i = 0; i < matrixSize_; ++i) { 
     delete [] matrixArray_[i]; 
    } 
    delete [] matrixArray_; 
} 

void matrix::printMatrix() const 
{ 
    for(int row = 0; row < matrixSize_; row++) { 
     for(int col = 0; col < matrixSize_; col++) { 
      cout << "test" << " "; 
      cout << matrixArray_[row][col] << endl; 
     }// end col 
     cout << endl; 
    }//end row 
} 

1: Ajout de « _ «suffixe et pourrait aussi bien faire que nous ne recevons pas accidentellement des ordures ici,

2: Ajout de « _ » suffixe et je privatisable de sorte qu'il ne soit pas retouché à l'extérieur,

3: Ajout d'un Fonction de membre accesseur 'size()',

4: Utilisez la liste des initialiseur pour copier le paramètre "matrixSize" à un membre "matrixSize_",

5: Suppression de la 'int **' et noter que nous utilisons 'matrixArray_' - membre,

6 : Le () après le new int[matrixSize_] dit au compilateur par défaut initialiser les colonnes pour nous (les définit à zéro) En C++ moderne ce serait {} à la place, mais alors je ne suis pas sûr si vous utilisez un compilateur C++ moderne et à la fois travail.

7: Ajout d'une destructor pour libérer la mémoire utilisée

Pour des raisons similaires, je vous encourage à envisager de faire vos noms de type distinct: class Matrix ou class matrix_t.

+0

Merci pour la critique point par point. J'essaie d'apprendre les meilleures pratiques et cela m'a vraiment aidé. – PixelPusher

+0

@TimBotelho Heureux que ça a aidé! Il est important d'avoir une certaine compréhension des tableaux et de l'allocation dynamique de la mémoire, mais le C++ moderne vous épargne un * lot * de la douleur causée par ces choses. Soyez sûr de bookmark [vector] (http://en.cppreference.com/w/cpp/container/vector), [unique_ptr] (http://en.cppreference.com/w/cpp/memory/unique_ptr) et [shared_ptr] (http://en.cppreference.com/w/cpp/memory/shared_ptr) pour une lecture ultérieure - mais pas trop tard - sauvez-vous beaucoup de douleur :) – kfsone