智能指针auto_prt(C++98)

智能指针auto_prt(C++98)

auto_ptr 是 c++ 98 定义的智能指针模板,其定义了管理指针的对象,可以将new 获得(直接或间接)的地址赋给这种对象。当对象过期时,其析构函数将使

用 delete 来释放内存!

1、用法

头文件:

#include

用 法:

auto_ptr<类型> 变量名(new 类型)

#include <iostream>
#include <string>
#include <exception>
#include <memory>

using namespace std;

//auto_ptr< Test> t(new Test()); //忠告 1: 智能指针不要定义为全局变量

class Test
{
public:
Test() {
	cout << "Test is construct" << endl;
	debug = 1;
} 
    
~Test() {
    cout << "Test is destruct" << endl;
}
    
int getDebug() {
return debug;
}
    
private:
	int debug;
};

//用 法: auto_ptr<类型> 变量名(new 类型)
void memory_leak_demo1() {
auto_ptr< Test> t(new Test());

//忠告 3: 除非自己知道后果,不要把 auto_ptr 智能指针赋值给同类型的另外一个智能指针
	auto_ptr< Test> t1;
	t1 = t;
	auto_ptr<Test>* tp = new auto_ptr<Test>(new Test()); //忠告 2: 不要定义指向智能指针对象的指针变量
    
	//在使用智能指针访问对象时,使用方式和普通指针一样
	cout<< "-> debug: "<<t->getDebug()<< endl;
	cout << "* debug: " << (*t).getDebug() << endl;
    
	Test* tmp = t.get();//获取到自己指向的位置给新的指针
	cout << "get debug: " << tmp->getDebug() << endl;
    
		//release 取消指针指针对动态内存的托管,之前分配的内存必须手动释放
		Test* tmp = t.release();
		delete tmp;
	//reset 重置智能指针托管的内存地址,如果地址不一致,原来的会被析构掉
	t.reset();
	t.reset(new Test());
    
	if(0){
	Test* t1 = new Test();
	t1->getDebug();
}
	return;
}

int memory_leak_demo2() {
	//Test* t = new Test();
	auto_ptr< Test> t(new Test());
{
	throw exception("文件不存在");
}
	//delete t;
	return 0;
}

int main()
{
	memory_leak_demo1();
/*try {
	memory_leak_demo2();
}catch (exception e) {
	cout << "catch exception: " << e.what() << endl;
}*/
	system("pause");
	return 0;
}

2、建议

1.尽可能不要将 auto_ptr 变量定义为全局变量或指针

2.除非自己知道后果,不要把 auto_ptr 智能指针赋值给同类型的另外一个智能指针

3.C++11 后 auto_ptr 已经被“抛弃”,已使用 unique_ptr 替代!

3、auto_prt弊端

auto_ptr 基于排他所有权模式:两个指针不能指向同一个资源,主要问题:

1、复制或赋值都会改变资源的所有权

2、在 STL 容器中使用 auto_ptr 存在重大风险,因为容器内的元素必需支持可复制(copyconstructable)和可赋值(assignable)。

3、不支持对象数组的内存管理

#include <stdio.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>
using namespace std;
int main() {
//弊端 1. auto_ptr 被 C++11 抛弃的主要理由 p1= p2 ,复制或赋值都会改变资源的所有权
	auto_ptr<string> p1(new string("I 'm martin."));
	auto_ptr<string> p2(new string("I 'm rock."));
	printf("p1: %p\n", p1.get());
	printf("p2: %p\n", p2.get());
	p1 = p2;
    printf("after p1 = p2\n");
	printf("p1: %p\n", p1.get());//p1为p2的值,之前值被delete
	printf("p2: %p\n", p2.get());//p2为0000000
    
//弊端 2. 在 STL 容器中使用 auto_ptr 存在重大风险,因为容器内的元素必需支持可复制(copy
	constructable)和可赋值(assignable)。
	vector<auto_ptr<string>> va;
	auto_ptr<string> p3(new string("I 'm p3."));
	auto_ptr<string> p4(new string("I 'm p4."));
	va.push_back(std::move(p3));//不支持左值,用move变成右值
	va.push_back(std::move(p4));

	cout <<"va[0]: "<< *va[0] << endl;
	cout <<"va[1]: "<< *va[1] << endl;
	//风险来啦
		va[0] = va[1];
		cout << "va[0]: " << *va[0] << endl;
		cout << "va[1]: " << *va[1] << endl;
    
	//弊端 3. 不支持对象数组的内存管理
	//auto_ptr<int[]> ai(new int[5]); //不能这样定义
	//auto_ptr 陷阱,不能把同一段内存交给多个 auto_ptr 变量去管理
	/*{
	auto_ptr<string> p2;
	string* str = new string("智能指针的内存管理陷阱");
	p2.reset(str);
{
	auto_ptr<string> p1;
	p1.reset(str);
}
	cout <<"str: " << *p2 << endl;
}*/
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值