C++_智能指针、强转指针

本文深入探讨C++中智能指针的四种类型:auto_ptr、unique_ptr、shared_ptr及weak_ptr,解析它们的工作原理、优缺点及应用场景,同时介绍四种强转指针的用法。

智能指针:
C++ 98
        auto_ptr
C++11
        unique_ptr shared_ptr weak_ptr 

auto_ptr:所有权唯一新的智能指针取消旧智能指针所有权 ,赋值或者拷贝导致智能指针提前失效  
(一个较为早期的版本(日常是不用的)解决拷贝构造(多次释放)的方法是管理权转移(以前的对象不再管理,把旧对象的管理空间的权限交给旧对象拷贝出的新对象,把旧对象管理空间的指针值交给新对象之后,把旧对象管理空间的指针赋为空),有效的避免了会出现多次释放,后来又有人提出这样的auto_ptr解决了之前的问题(多设了一个变量 _owner,是一个bool 值 ,用来指定拥有空间的拥有者,只有_ower为true的对象才可以释放空间 (这种方法其实不好,原因是当拥有者释放掉了空间时,会有许多野指针的产生(_ower不为true对象管理空间的指针都将变为野指针))

unique_ptr:核心是防拷贝,通过只声明不定义拷贝构造和赋值运算符且声明成私有(推荐使用,在不用拷贝的情况)所有权唯一,缺点:不能数据共享 

shared_ptr:强智能指针:加一个引用计数,引用计数为0时释放,可以在需要拷贝的地方使用,弥补了auto_ptr的缺陷。缺点:可能引起智能指针相互引用造成内存泄漏

weak_ptr:弱智能指针:解决强智能指针相互引用的问题加引用计数,不能单独使用,与shared_ptr配合使用

四种强转指针:
const_cast:去除常性的转换,编译时完成
static_cast:可以实现C++中内置基本数据类型之间的相互转换,安全性更高,编译时完成
reinterpret_cast:C指针,编译时完成
dynamic_cast:运行时处理的,运行时要进行类型检查,不能用于内置的基本数据类型的强制转换,转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL,使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过,在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时dynamic_cast具有类型检查的功能,比static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

C++中,可以使用强制类型转换将结构体指针转换为`char*`类型。以下是不同场景下的示例代码: ### 简单结构体指针转换 如果结构体的内存是连续的,也就是结构体内没有指针成员指向其他内存区域,那么可以直接使用`reinterpret_cast`进行强制类型转换。示例代码如下: ```cpp #include <iostream> // 定义一个简单的结构体 struct SimpleStruct { int num; char ch; }; int main() { SimpleStruct s; s.num = 10; s.ch = 'A'; // 将结构体指针强制转换为char* char* charPtr = reinterpret_cast<char*>(&s); // 输出转换后的char*指针指向的内容 for (size_t i = 0; i < sizeof(SimpleStruct); ++i) { std::cout << static_cast<int>(charPtr[i]) << " "; } std::cout << std::endl; return 0; } ``` ### 包含指针成员的结构体指针转换 当结构体中包含指针成员时,其内存地址不一定是连续的,不能直接将整个结构体进行转换。需要分别处理结构体成员。可以参考以下示例代码(结合引用[2]的思路): ```cpp #include <iostream> #include <cstring> #include <cstdlib> // 定义包含指针成员的结构体 typedef struct { int len; char* ptr; } SDM_OCTET_STRING; int main() { const char* sdata = "Hello"; SDM_OCTET_STRING *data = static_cast<SDM_OCTET_STRING*>(calloc(1, sizeof(SDM_OCTET_STRING))); data->len = strlen(sdata); data->ptr = static_cast<char*>(calloc(data->len + 1, sizeof(char))); memcpy(data->ptr, sdata, data->len); SDM_OCTET_STRING *normal_data = static_cast<SDM_OCTET_STRING*>(calloc(1, sizeof(SDM_OCTET_STRING))); normal_data->len = data->len + sizeof(data->len); normal_data->ptr = static_cast<char*>(calloc(normal_data->len, sizeof(char))); memcpy(normal_data->ptr, &data->len, sizeof(data->len)); memcpy(normal_data->ptr + sizeof(data->len), data->ptr, data->len); // 将处理后的结构体指针转换为char* char* charPtr = reinterpret_cast<char*>(normal_data); // 输出转换后的char*指针指向的内容 for (size_t i = 0; i < normal_data->len; ++i) { std::cout << static_cast<int>(charPtr[i]) << " "; } std::cout << std::endl; // 释放内存 free(data->ptr); free(data); free(normal_data->ptr); free(normal_data); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值