C++基础知识-之智能指针(韦东山视频学习)

初始化

#include <iostream>                                                             
#include <string.h>                                                             
#include <unistd.h>                                                             
using namespace std;                                                            
                                                                                                                                                                                                                                                                              
class Person {                                                                  
public:                                                                         
                                                                                
        Person() {                                                              
                cout <<"Pserson()"<<endl;                                          
        }                                                                          
        ~Person()                                                                  
        {                                                                          
                cout << "~Person()"<<endl;                                         
        }                                                                          
        void printInfo(void)                                                       
        {                                                                          
                cout<<"just a test function"<<endl;                                
        }                                                                          
}

class sp {                                                                         
private:                                                                           
        Person *p=NULL;                                                            
public:                                                                            
        sp() : p(0) {}                                                             
        sp(Person *other)                                                          
        {                                                                          
                cout<<"sp(const Person *other)"<<endl;                             
                p = other;                                                         
        }                                                                          
        sp(int i)                                                                  
        {                                                                          
                cout<<"sp(int="<<i<<")"<<endl;                                     
        }                                                                          
        ~sp()                                                                      
        {                                                                          
                cout<<"~sp()"<<endl;                                               
                if (p)                                                             
                        delete p;                                                  
        }                                                                          
        Person *operator->()                                                       
        {                                                                          
                return p;                                                          
        }                                                                          
                                                                                   
};
void test_func(void)                                                            
{                                                                               
        sp i1(5);                                                               
        sp i2 = 6;                                                              
        sp s = new Person();                                                    
        sp s3(new Person) ;        
        s3->printInfo();
                                                     
                                                                                
}                                                                               
                                                                                
int main(int argc, char **argv)                                                 
{                                                                               
        test_func();                                                            
        return 0;                                                               
} 

初始化变量两种方法:

第一种方法:

class sp;
int k=2;
sp i1(k);   //定义sp对象i1,并传入int类型,初始化参数,将调用 sp(int i)  。

第二种方法:
sp i2 = k;  ///定义sp对象i2,并传入int类型的k变量,初始化参数,将调用 sp(int i)  。

说明:

  1. 使用右值传参法,调用对象的对应析构函数来构造对象。

sp s3(new Person) ;
s3->printInfo();
s3中没有printInfo函数,但是sp对象重载了->符号,返回了sp中person类型的私有数据p的指针tmp,指针再调用printInfo函数。

2. 问题推导

void test_func(void)                                                               
{                                                                                  
        Person *p = new Person();                                                  
        per.printInfo();                                                                                                                                                    
}                                                                                  
                                                                                   
int main(int argc, char **argv)                                                    
{                                                                                  
        int i;                                                                     
                                                                                   
        for (i = 0; i < 2; i++)                                                    
                test_func();                                                       
        return 0;                                                                  
} 

在 test_func中,使用new Person开辟的内存,没有释放,没有执行Person类的析构函数。

改进1:在test_func中,使用局部变量,执行Person类的析构函数。

void test_func(void)                                                               
{                                                                                  
        Person per;                                                     
        per.printInfo();                                                                                                                                                    
}                                                                                  
                                                                                   
int main(int argc, char **argv)                                                    
{                                                                                  
        int i;                                                                     
                                                                                   
        for (i = 0; i < 2; i++)                                                    
                test_func();                                                       
        return 0;                                                                  
} 

改进2:
如果
如果函数test_func,是person类指针,则可以在函数test_func申请一个sp类变量A,在sp类中包含person类指针,在释放sp类的析构函数中,如果sp类中的person类指针被赋值,则删除person类指针指向的内存。

class sp {                                                                         
private:                                                                           
        Person *p;                                                                 
                                                                                                                                                                            
public:                                                                            
        sp() : p(0) {}                                                             
                                                                                   
        sp(Person *other)                                                          
        {                                                                          
                cout<<"sp(const Person *other)"<<endl;                             
                p = other;                                                         
        }                                                                          
                                                                                   
        sp(sp &other)                                                              
        {                                                                          
                cout<<"sp(const Person *other)"<<endl;                             
                p = other.p;                                                       
        }                                                                          
                                                                                   
        ~sp()                                                                      
        {                                                                          
                cout<<"~sp()"<<endl;                                               
                if (p)                                                             
                        delete p;                                                  
        }                                                                          
                                                                                   
        Person *operator->()                                                       
        {                                                                          
                return p;                                                          
        }                                                                          
                                                                                   
};

void test_func(sp &other)                                                       
{                                                                               
        sp s = other;                                                           
                                                                                
        s->printInfo();                                                         
                                                                                                                                                                            
} 

int main(int argc, char **argv)                                                    
{                                                                                  
                                                                                   
        sp other = new Person();                                                   
        test_func(other);                                                          
                                                                                                                                                                            
        cout<<"main() end"<<endl;                                                  
                                                                                   
        return 0;                                                                  
}  

说明:

  1. main函数
    sp other = new Person();==>Person *per1 = new Person(); sp other(per1),声明了一个名为other的sp对象。
    2)test_func函数中
    sp &other1=other;
    sp s = other1; ==>则会调用构造函数
    sp(sp &other)
    {
    cout<<“sp(const Person *other)”<<endl;
    p = other.p;
    }
    sp &other = other1; //引用不能等于临时变量。
    const sp &other = other1;

修改3:析构函数修改为const sp &,修改代码如下:

class sp {                                                                                                                                     
                                                                                   
        sp(const sp &other)                                                              
        {                                                                          
                cout<<"sp(const Person *other)"<<endl;                             
                p = other.p;                                                       
        }                                                                          
                                                                                   
}

修改4:引入计数


 43         ~sp()                                                                   
 44         {                                                                       
 45                 cout<<"~sp()"<<endl;                                            
 46                 if (p)                                                          
 47                 {                                                               
 48                         cout<<"~sp() before delete!"<<endl;                     
 49                         delete p;                                               
 50                         p = NULL;                                               
 51                         cout<<"~sp() after delete!"<<endl;                      
 52                 }                                                               
 53         }  

 62 void test_func(sp &other)                                                       
 63 {                                                                               
 64         sp s = other;                                                                                                             
 66         s->printInfo();                                                         
 67 }                                                                               
 68                                                                                 
 69 int main(int argc, char **argv)                                                 
 70 {                                                                               
 71                                                                                 
 72         sp other = new Person();                                                                                                                                        
 73         test_func(other);                                                       
 74                                                                                 
 75         cout<<"main() end"<<endl;                                               
 76                                                                                 
 77         return 0;                                                               
 78 }  

1
在test_func执行结束时候,销毁other,执行sp类析构函数,判断p不为空,则delete p指向的p1;在main函数执行结束后,销毁s1,显然p=123456,不为空,再次销毁p,会产生错误。
改进6:引入计数,当是最后一个使用者,销毁p。
解决程序如下:

  8 class Person {                                                                  
  9 private:                                                                        
 10         int count;                                                              
 11                                                                                 
 12 public:                                                                         
 13         void incStrong(){ count++; }                                            
 14         void decStrong(){ count--; }                                            
 15         int getStrongCount(){ return count;}                                    
 16                                                                                 
 17         Person() : count(0){                                                    
 18                 cout <<"Pserson()"<<endl;                                       
 19         }                                                                       
 20                                                                                 
 21                                                                                 
 22         ~Person()                                                               
 23         {                                                                       
 24                 cout << "~Person()"<<endl;                                      
 25         }                                                                       
 26         void printInfo(void)                                                    
 27         {                                                                       
 28                 cout<<"just a test function"<<endl;                             
 29         }                                                                       
 30 }; 

 46         sp(const sp &other)                                                     
 47         {                                                                       
 48                 cout<<"sp(const sp &other)"<<endl;                              
 49                 p = other.p;                                                    
 50                 p->incStrong();                                                 
 51         }                                                                       
 52                                                                                 
 53         ~sp()                                                                   
 54         {                                                                       
 55                 cout<<"~sp()"<<endl;                                            
 56                                                                                 
 57                 if (p)                                                          
 58                 {                                                               
 59                         p->decStrong();                                         
 60                         //cout<<"~sp() delete1"<<p->getStrongCount<<endl;       
 61                         cout<<"~sp() cout="<<p->getStrongCount()<<endl;         
 62                         if (p->getStrongCount() == 0)                           
 63                         {                                                       
 64                                 cout<<"~sp() delete"<<endl;                     
 65                                 delete p;                                       
 66                                 p = NULL;                                       
 67                         }                                                       
 68                 }                                                                                                                                                       
 69         }  
发布了112 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chengbeng1745/article/details/104013901