Titre : Il n'y a qu'une seule erreur dans chaque fonction dans la définition de la classe de tableau d'entiers suivante. Trouvez-la et corrigez-la
class ArrayInt { public: ArrayInt(const int *pArray, int size) : m_nSize(size) { assert(size > 0); for (int i = 0; i < size; ++ i) m_pArray[i] = pArray[i]; } ArrayInt(const ArrayInt &iCopy):m_nSize(iCopy.m_nSize),m_pArray(iCopy.m_pArray){} ~ArrayInt() { delete m_pArray; } int operator[](short index) { assert(index < m_nSize); return m_pArray[index]; } const ArrayInt & operator=(const ArrayInt & iCopy) { assert(m_nSize >= iCopy.m_nSize); for (int i = 0; i < m_nSize; ++ i) m_pArray[i] = iCopy.m_pArray[i]; } private: short m_nSize; int * m_pArray; };
Analyse : Les erreurs ci-dessus constituent les connaissances les plus élémentaires en C++ et sont également les plus déroutantes. . Une chose à noter à propos des constructeurs de copie est le problème de la copie profonde et de la copie superficielle. Chaque problème des fonctions ci-dessus est décrit comme suit :
1. L'affectation démarre sans allouer d'espace à l'intérieur du constructeur ;
2 Le constructeur de copie est une copie superficielle, ce qui fait que les deux objets partagent une mémoire
3. La mémoire du tableau doit être supprimée en interne et le pointeur doit être attribué à vide
4. La vérification des limites d'indice de la fonction de l'opérateur parenthèse est incomplète. Lorsque l'index est une valeur négative, le programme plante
5. La fonction opérateur d'affectation n'a pas de valeur de retour et renvoie Le rôle de la valeur est d'attribuer en continu a = b = c
La correction du programme est la suivante :
class ArrayInt { public: ArrayInt(const int *pArray, int size) : m_nSize(size) { assert(size > 0); m_pArray = new int[size]; for (int i = 0; i < size; ++ i) m_pArray[i] = pArray[i]; } ArrayInt(const ArrayInt & iCopy) { //ArrayInt(iCopy.m_pArray, iCopy.m_nSize); m_nSize = iCopy.m_nSize; assert(m_nSize > 0); m_pArray = new int[m_nSize]; for (int i = 0; i < m_nSize; ++ i) m_pArray[i] = iCopy.m_pArray[i]; } ~ArrayInt() { if (m_pArray) { delete[] m_pArray; m_pArray = NULL; } //printf("distructor is called\n"); } int operator[](short index) { assert(index < m_nSize && index >= 0); return m_pArray[index]; } const ArrayInt & operator=(const ArrayInt & iCopy) { if (this == &iCopy) return *this; assert(m_nSize >= iCopy.m_nSize); for (int i = 0; i < iCopy.m_nSize; ++ i) m_pArray[i] = iCopy.m_pArray[i]; return *this; } private: short m_nSize; int * m_pArray; };
Explication : Dans le constructeur de copie, ce n'est pas faisable pour essayer d'appeler le constructeur pour implémenter la copie profonde, car cela générera un objet anonyme dans le constructeur. Une fois le constructeur de copie appelé, l'objet est détruit (vous pouvez le vérifier en imprimant des caractères dans le destructeur), donc une copie profonde. et l'anonymat ne sont pas implémentés comme on l'imagine. L'objet implémente une copie approfondie. Par conséquent, lors d’un accès externe aux données membres de l’objet qui appelle le constructeur de copie, une erreur sera signalée.
La fonction de test est la suivante :
void test_construct_copy() { int pArray[] = {1, 2, 3, 5}; ArrayInt arr(pArray, sizeof pArray / sizeof(int)); printf("%d \n", arr[2]); ArrayInt arr2(arr); printf("%d \n", arr2[2]); pArray[2] = 8; ArrayInt arr3(pArray, 4); printf("%d \n", arr3[2]); arr3 = arr2; printf("%d \n", arr3[2]); pArray[2] = 10; ArrayInt arr4(pArray, 4); arr3 = arr2 = arr4; printf("%d \n", arr3[2]); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!