暑假了...在光谷找了份工作,从事c/c++方面的数据恢复与手机取证方面的编码工作......要求对c/c++,数据结构与算法,复合文档结构有所了解....回想上次对C++的系统学习是看的老谭的一本书,大概过去半年有余了,没有再看过什么C++上的书了,心里一直空落落的,抽暑假正好翻出磁盘里原来整理的书籍读一读,正在读的这本书叫The C++ Standard Library,网上有侯捷先生译本的,但是很模糊,只好直接看英文版本了.正好无事,就看一点写一点,加深自己的记忆与理解......
话说这篇文章是讲一下智能指针的,英文名为:smart pointer,首先,顾名思义,这种指针是智能的,和一般的指针是有所不同的,我们以开辟一个实例(对象,因为个人读到了python书中的一切皆对象的话,所以感觉将C++中的对象称为实例更为悦耳.....个人观点,见笑.....)为例:
example:
传统指针:
#include <iostream>
class Cdemo{
private:
int m_age;
char m_sex;
public:
//constructor and ~constructor
Cdemo(int para_age,char para_sex);
~Cdemo();
protected:
};
/*Cdemo*/
//constructor and ~constructor
//1
Cdemo::Cdemo(int para_age,char para_sex)
{
m_age = para_age;
m_sex = para_sex;
std::cout << "Cdemo instanced";
}
Cdemo::~Cdemo()
{
std::cout << "Cdemo destroyed";
system("pause");
}
int main(int argc,char *argv[])
{
Cdemo *ptr = new Cdemo(21,'m');
delete ptr;
return (0);
}
![](https://img-my.csdn.net/uploads/201207/13/1342156641_1569.png)
智能指针:
#include <iostream>
#include <memory>
class Cdemo{
private:
int m_age;
char m_sex;
public:
//constructor and ~constructor
Cdemo(int para_age,char para_sex);
~Cdemo();
protected:
};
/*Cdemo*/
//constructor and ~constructor
//1
Cdemo::Cdemo(int para_age,char para_sex)
{
m_age = para_age;
m_sex = para_sex;
std::cout << "Cdemo instanced" << std::endl;
}
Cdemo::~Cdemo()
{
std::cout << "Cdemo destroyed" << std::endl;
system("pause");
}
int main(int argc,char *argv[])
{
std::auto_ptr<Cdemo> ptr( new Cdemo(21,'m') );
return (0);
}
运行结果与上面的传统指针一模一样,可见,所谓智能指针,其最神奇之处就是可以自动释放所指向的实例,在什么情况下可以自动释放呢?当这个智能指针被销毁时;
那么,智能指针进行运算时需要注意什么???
1.所有权的转交(所有权就是一个实例被哪一个智能指针所关联[当然,有可能一个实例被多格智能指针关联,显然这是个坏主意.....])
所谓所有权转交,就是将一个智能指针指向的实例关联到另一个智能指针上去,那么原先的智能指针就悬空了,不过此时,实例是没有被释放的.....
比如:
std::auto_ptr<Cdemo> ptr1( new Cdmeo(22,'m') ); //此时new出来的实例的所有权归ptr1
std::auto_ptr<Cdemo> ptr2; //此时ptr2悬空
ptr2 = ptr1; //此时实例的所有权进行转交,ptr1悬空,ptr2关联到实例
2.传值性访问
传值是函数参数传递的一种方式,另外还是引用传递或者传址,这里仅讨论传值访问给智能指针带来的注意事项.由于有所有权转交的存在,所以当进行参数传值时很显然原先的智能指针被转交了实例的所有权,而函数参数获得了实例的所有权,如果在函数里面不继续传递下去的话,那么当函数执行完成时实例即被释放,原先的智能指针被悬空,这可能是你想要的结果,但多数时候可能带来问题....比如:
#include <iostream>
#include <memory>
class Cdemo{
public:
int m_age;
char m_sex;
public:
//constructor and ~constructor
Cdemo(int para_age,char para_sex);
~Cdemo();
protected:
};
/*Cdemo*/
//constructor and ~constructor
//1
Cdemo::Cdemo(int para_age,char para_sex)
{
m_age = para_age;
m_sex = para_sex;
std::cout << "Cdemo instanced" << std::endl;
}
Cdemo::~Cdemo()
{
std::cout << "Cdemo destroyed" << std::endl;
system("pause");
}
//print
void critical_print(std::auto_ptr<Cdemo> para_ptr)
{
std::cout << "critical print: " << para_ptr->m_age << " " << para_ptr->m_sex << " " << std::endl;
}
int main(int argc,char *argv[])
{
std::auto_ptr<Cdemo> ptr( new Cdemo(21,'m') );
critical_print(ptr);
std::cout << "the main function is dying" << std::endl; //此时,main函数还没死去,即智能指针ptr理应还未释放所关联的实例
system("pause");
return (0);
}
![](https://img-my.csdn.net/uploads/201207/13/1342158497_9460.png)
从运行结果可以看到,在main还未结束时实例就被释放了,可见这里的critical_print参数的传递导致了ptr所有权的转交,在critical_print结束之后实例便被释放了,如果此时再对main函数中的ptr进行任何赋值或者传递操作都将是致命的危险.........而我们的本意不过是打印数据进行只读操作,在无声无息之中,就进行了一些写性的操作.....避免(应该说是发现)这个问题的比较好的解决方法是加上const,即const std::auto_ptr<Cdemo> ptr( new Cdemo(22,'m') );,此时ptr关联实例的所有权将不能进行转交,但是也不能进行传值或者任何的复制操作了...........
关于更多的智能指针话题可以参看原书
注意事项:
1.传统指针与智能指针赋值是不能进行的.譬如:std::auto_ptr<int> ptr = new int;这是错的....