指針學習1--new &delete & destructor
1. 一般指針的new&delete
對于指針a,delete a之后,指針a 的地址仍然是原來的地址(并不是NULL),只不過所指向的對象被釋放了,此時指針存放的值為隨機的,由編譯器確定。
1
int *a = new int(2);
2
cout << "after new :" << endl;
3
cout << "a = " << a << "," << "*a = " << *a << endl;
4
5
delete a;
6
cout << "after delete: " << endl;
7
if(a == NULL)
8
{
9
cout << "a is null after delete" << endl;
10
}
11
else
12
{
13
cout << " a is not null after delete" << endl;
14
}
15
cout << "a = " << a << "," << "*a = " << *a << endl;
int *a = new int(2);2
cout << "after new :" << endl;3
cout << "a = " << a << "," << "*a = " << *a << endl;4

5
delete a;6
cout << "after delete: " << endl;7
if(a == NULL)8

{9
cout << "a is null after delete" << endl;10
}11
else12

{13
cout << " a is not null after delete" << endl;14
}15
cout << "a = " << a << "," << "*a = " << *a << endl;
//好的編程習慣
delete a;
a = NULL;常規方法創建的對象,當實際對象(而不是對象的引用)超出作用域時,才會運行析構函數
動態方法創建的對象,當刪除指向動態分配對象的指針時,才會運行析構函數。
2. 一般類對象的聲明與初始化:不用new也可以定義類對象(區別于java),默認調析構函數
注:為方便簡單演示,并沒有遵循三法則
1
class Stu
2

{
3
public:
4
Stu(int m):var(m)
5
{
6
var = m;
7
cout << "constructor called." << endl;
8
}
9
~Stu()
{ cout << var << " destructor called." << endl;}
10
private:
11
int var;
12
};
13
14
void func()
15

{
16
//調用構造函數
17
Stu a(20);
18
//調用默認復制構造函數
19
Stu b(a);
20
//等價于Stu temp(b); Stu b(temp);
21
//所以有調用構造函數的過程
22
Stu c = 30;
23
//都是用隱式方式定義的,所以不用delete,自動調用析構函數
24 | //注意析構的順序
25
}
26
27
int main()
28

{
29
func();
30
return 0;
31
}
class Stu2


{3
public:4
Stu(int m):var(m)5

{ 6
var = m;7
cout << "constructor called." << endl;8
} 9

~Stu()
{ cout << var << " destructor called." << endl;} 10
private:11
int var; 12
};13

14
void func()15


{16
//調用構造函數17
Stu a(20);18
//調用默認復制構造函數19
Stu b(a); 20
//等價于Stu temp(b); Stu b(temp); 21
//所以有調用構造函數的過程22
Stu c = 30; 23
//都是用隱式方式定義的,所以不用delete,自動調用析構函數24 | //注意析構的順序
25
}26

27
int main()28


{29
func(); 30
return 0;31
}
這里有一個需要注意的地方,就是如果func里面的代碼是直接寫在main里的則不一定調用析構函數 ,由編譯器決定。
上面是dev c++, 下面是vc6.0的運行結果
1
2
int main()
3

{
4
5
//{
6
//調用構造函數
7
Stu a(20);
8
//調用默認復制構造函數
9
Stu b(a);
10
//等價于Stu temp(b); Stu b(temp);
11
//所以有調用構造函數的過程
12
Stu c = 30;
13
//new出來的指針對象,必須顯示delete,如a,b
14
//類對象結束局部范圍后會自動調用析構函數 如c
15
//}
16
return 0;
17
}

2
int main()3


{4

5
//{6
//調用構造函數7
Stu a(20);8
//調用默認復制構造函數9
Stu b(a); 10
//等價于Stu temp(b); Stu b(temp); 11
//所以有調用構造函數的過程12
Stu c = 30; 13
//new出來的指針對象,必須顯示delete,如a,b14
//類對象結束局部范圍后會自動調用析構函數 如c 15
//}16
return 0;17
}
3. 用new定義類對象,必須delete
動態分配的對象只有在指向該對象的指針被刪除時才撤銷。如果沒有刪除指向動態對象的指針,則不會運行該對象的析構函數,對象則一直存在,從而導致內存泄露。
常規方法創建的對象,當實際對象(而不是對象的引用)超出作用域時,才會運行析構函數
動態方法創建的對象,當刪除指向動態分配對象的指針時,才會運行析構函數。
1
class Stu
2

{
3
public:
4
Stu(int m):var(m)
5
{
6
var = m;
7
cout << "constructor called." << endl;
8
}
9
~Stu()
{ cout << var << " destructor called." << endl;}
10
private:
11
int var;
12
};
13
14
void func()
15

{
16
//調用構造函數
17
Stu* a = new Stu(20);
18
//調用默認復制構造函數
19
Stu* b= new Stu(*a);
20
//等價于Stu temp = new Stu(30); Stu b(temp);
21
//所以有調用構造函數的過程
22
Stu c = 30;
23
//new出來的指針對象,必須顯示delete,如a,b
24
//類對象結束局部范圍后會自動調用析構函數 如c
25
delete a;
26
delete b;
27
}
28
29
int main()
30

{
31
func();
32
return 0;
33
}
class Stu2


{3
public:4
Stu(int m):var(m)5

{ 6
var = m;7
cout << "constructor called." << endl;8
} 9

~Stu()
{ cout << var << " destructor called." << endl;} 10
private:11
int var; 12
};13

14
void func()15


{16
//調用構造函數17
Stu* a = new Stu(20);18
//調用默認復制構造函數19
Stu* b= new Stu(*a); 20
//等價于Stu temp = new Stu(30); Stu b(temp); 21
//所以有調用構造函數的過程22
Stu c = 30; 23
//new出來的指針對象,必須顯示delete,如a,b24
//類對象結束局部范圍后會自動調用析構函數 如c25
delete a;26
delete b;27
}28

29
int main()30


{31
func(); 32
return 0;33
}
posted on 2010-04-18 10:58 幸運草 閱讀(796) 評論(0) 編輯 收藏 引用 所屬分類: C++

