C++智能指针与普通指针的简单比较

前言

指针的优点:

1)可以提高程序的编译效率和执行速度,使程序更加简洁。
2)可以作为函数返回值返回,从而实现函数和被调用函数两者间的双向通信。
3)利用指针可以实现动态内存分配。
4)可用于表示和实现各种复杂的数据结构,进而编写出高质量的程序。
5)可直接操作内存地址,从而可完成和汇编语言类似的工作。

指针的缺点:

1)空指针(没有赋值的指针变量(没有指向内存变量的地址))、指针悬空(指针指向的内存已释放,但指针的值没有被清零,对悬空指针操作的结果不可预知)或野指针(指的是没有被初始化过的指针)会造成程序崩溃。
2)指针多嵌套理解难度大。如:int (*func)(int *p); int (*func)(int *p, int (f)(int));

普通指针

指针间的赋值

int main()
{
// #1
int x;
int y;
int *p= &x;
int *q= &y;
x=43;
y=65;

// #2
 p=q;
*p=90;
std::cout<< x << " "<< y << std::endl;
std::cout  << *p << " " << *q << std::endl;
return 0;
}

输出结果:

43 90
90 90 

分析:#1部分 p指向x的地址,q指向y的地址;#2部分 指针q赋给指针p后,p和q都指向y的地址。

普通指针受作用域限制

 int main()
 {
   int a=5;
   {
     int *p;
     int *q=new int;
     p = &a;
     q = &a;
     }
     
     return 0;
   }

定义了一个普通指针p 、new了一个指针q。指针p的作用是大括号内,出了大括号就会自动消失。但是指针q使用new开辟了内存空间,出了大括号后开辟的内存空间依然存在,如果不delete,那块空间会一直存在,不能直接使用,导致内存泄漏。但。。。。是。。。。出了大括号后,虽然q指向的内容还存在,但是指针q已经不能使用了!它的作用域只在{}内。如果在括号外使用q会造成程序崩溃。

 int main()
 {
   int a=5;
   {
     int *p;
     int *q=new int;
     p = &a;
     q = &a;
    }
    std::cout<< *q <<std::endl; //wrong q is not defined
     return 0;
   }

为防止内存泄漏,可以在{}内最下面加上delete q;但是专门为局部指针开辟了内存空间,有什么用呢?出了局部作用域,就不能使用了。
不过如果局部指针作为函数值类型,就可以局部作用域外使用。如:

class Student{
public:
    std::string name;
};

Student* PrintName(){
    Student *stu = new Student;
    stu->name = std::string("Hello");
    return stu;  //return the pointer
}
int main(){
    Student* stu = PrintName();
    std::cout<<stu->name<<std::endl;
    delete stu;
}

可以把new定义的指针作为值传递出去。而没有new的指针是不行的。

智能指针

智能指针,只管创建不用我们自己销毁。常用的有shared_ptr, unique_ptr以及weak_ptr。用智能指针实现下

int main()
{
std::shared_ptr<int> p(new int());
{
   std::shared_ptr<int>   q=std::make_shared<int>();
   int a=10;
   *q=a;
   p=q;
   }
   std::cout<<*p<<std::endl;
return 0;
}

*p输出结果为10。智能指针类负责销毁new的内存空间。

int main()
{
int *p=new int;
{
   int *q=new int;
   int a=10;
   q=&a;
   p=q;
   delete q;
   }
   std::cout<<*p<<std::endl;
return 0;
}

程序崩溃了,因为销毁q时,q所指向的内存也被销毁了。指针p指向已经销毁的内存空间,所以崩溃了。

你可能感兴趣的:(C++,c++)