今天在學習時隨手編了一個小程序, 然而運行時卻發(fā)現(xiàn)總在出錯,而且每次的斷電都顯示在析構函數(shù)的delete 一行。起初時時百思不得,后來才發(fā)現(xiàn)問題所在,自我反思后覺得這是一個對我這樣的初學者來講很重要的問題。 問題出在PRint函數(shù)上是很明顯的,但到底是什么原因呢?#include<iostream>using namespace std;class Person{public : Person() { name = NULL; cout << "Default consturctor called!/n/n"; } Person(char *str) { name = new char [strlen(str) + 1]; strcpy_s(name, strlen(str) + 1, str); cout << "Consturctor called!/n/n"; } ~Person() { delete[] name;//斷點總在此處 cout << "Destructor called!/n/n"; } friend ostream& Operator << (ostream& out, Person &A) { out << A.name << endl; return out; } friend istream& operator >> (istream& in, Person &A) { char temp[10]; in.getline(temp, 10); int len = strlen(temp) + 1; A.name = new char[len]; strcpy_s(A.name, len, temp); return in; } friend void Print(Person a) { cout << a.name << endl; }private : char *name;};int main(){ Person a("mike"); //cin >> a; Print(a); //cout << a; system("pause"); return 0;}關鍵在于深淺拷貝的問題,這里可以看到在Print函數(shù)中傳過去的是一個對象,要命就要命在成員中有一個指針。 我們知道, C++中將對象作為參數(shù)時,并非將對象直接傳過去,而是調用拷貝構造函數(shù)傳過去一個對象的副本。而在函數(shù)結束后調用析構函數(shù)。當函數(shù)中沒有定義拷貝構造函數(shù)時,就會調用默認的拷貝構造函數(shù)。但不幸的是這個默認的函數(shù)采用的是“淺拷貝”,也就是說它僅僅將指針本身的值復制過去。造成的后果是兩個指針指向同一處,這樣在函數(shù)結束后調用析構函數(shù)釋放該處內存空間, 在程序結束后又是釋放一次,自然就導致了錯誤。 解決方法很簡單,定義一個拷貝構造函數(shù)就行了。
Person(const Person &a) { name = new char[strlen(a.name) + 1]; strcpy_s(name, strlen(a.name) + 1, a.name); cout << "Copy constructor called!/n/n"; }由此可以得到一個教訓:當成員中含指針是, 必須要自定義拷貝構造函數(shù)。
新聞熱點
疑難解答