关于C++的指针与对象

来源:互联网 发布:linux tomcat启动java 编辑:程序博客网 时间:2024/05/20 13:07

指针与对象

不管是类还是结构(其实结构是一种特殊的类),它们在创建时还是要创建内存的,但是,创建类的对象也有两种方式,直接声明和用指针来分配新实例。

[cpp] view plaincopyprint?
  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. class Test  
  5. {  
  6. public:  
  7.     Test();  
  8.     ~Test();  
  9.     void Do(char* c);  
  10. };  
  11.   
  12. Test::Test()  
  13. {  
  14.     cout << "Test对象被创建。" << endl;  
  15. }  
  16. Test::~Test()  
  17. {  
  18.     cout << "Test对象被销毁。" << endl;  
  19. }  
  20. void Test::Do(char* c)  
  21. {  
  22.     cout << "在" << c << "中调用了Do方法。" << endl;  
  23. }  
  24.   
  25. void Func1()  
  26. {  
  27.     Test t;  
  28.     t.Do("Func1");  
  29.     /* 
  30.     当函数执行完了,t的生命周期结束,发生析构。 
  31.     */  
  32. }  
  33.   
  34. void Func2()  
  35. {  
  36.     Test* pt = new Test;  
  37.     pt -> Do("Func2");  
  38.     /* 
  39.     用指针创建的对象,就算指针变量的生命周期结束,但内存中的对象没有被销毁。 
  40.     因此,析构函数没有被调用。 
  41.     */  
  42. }  
  43.   
  44. int main()  
  45. {  
  46.     Func1();  
  47.     cout << "---------------------" << endl;  
  48.     Func2();  
  49.     getchar();  
  50.     return 0;  
  51. }  


我们来看看这个例子,首先定义了一个类Test,在类的构造函数中输出对象被创建的个息,在发生析构时输出对象被销毁。

接着, 我们分别在两个函数中创建Test类的对象,因为对象是在函数内部定义的,根据其生命周期原理,在函数返回时,对象会释放,在内存中的数据会被销毁。理论上是这样的,那么,程序实际运行后会如何呢?

 

这时候我们发现一个有趣的现象,在第一个函数直接以变量形式创建的对象在函数执行完后被销毁,因为析构函数被调用;可是,我们看到第二个函数中并没有发生这样的事,用指针创建的对象,在函数完成时居然没有调用析构函数。

直接创建对象,变量直接与类实例关联,这样一来,当变量的生命周期结束时,自然会被处理掉,而用指针创建的实例,指针变量本身并不存储该实例的数据,它仅仅是存了对象实例的首地址罢了,指针并没有与实例直接有联系,所以,在第二个函数执行完后,被销毁的是Test*,而不是Test的对象,仅仅是保存首地址的指针被释放了而已,而Test对象依然存在于内存中,因此,在第二个函数完成后,Test的析构函数不会调用,因为它还没死呢。

那么,如何让第二个函数在返回时也销毁对象实例呢?还记得吗,我前文中提过。对,用delete.。

[cpp] view plaincopyprint?
  1. void Func2()  
  2. {  
  3.     Test* pt = new Test;  
  4.     pt -> Do("Func2");  
  5.     delete pt;  
  6. }  


现在看看,是不是在两个函数返回时,都能够销毁对象。

 

现在你明白了吧?

由此,可以得出一个结论:指针只负责为对象分配和清理内存,并不与内存中的对象实例有直接关系。