《白话C++》第9章 泛型,Page847~849 AutoPtr 允许从外部指针构造

2024-02-17 17:52

本文主要是介绍《白话C++》第9章 泛型,Page847~849 AutoPtr 允许从外部指针构造,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

允许从外部指针构造

这个版本的AutoPtr仍然还有很多不完美的地方,比如它在构造函数中,一定要new出一个对象,因此无法表达一个“空指针”,也无法“接管”一个已经存在的外部指针,另外,两个(同质的)AutoPtr<T>对象之间,如何赋值,靠被也未实现。

托管外来指针

让它可以托工外来的指针,暂时只要修改它的构造函数即可:

template <typename T>
struct AutoPtr
{AutoPtr() //默认的构造过程: _ptr(nullptr) //_ptr将是一个空指针{}explicit AutoPtr(T* ptr) //构造时,接管一个外部的指针: _ptr(ptr){}...//析构及其他原有操作不变
};

现在,我们可以这样使用AutoPtr<T>了:

AutoPtr <S> sap;
sap->a = 10; //不要这样,会死的,sap._ptr当前是NULL.
S* s = new S; //用普通的方式,创建了s指针,后面的代码中,千万不能delete s
AutoPtr <S> sap2(s); //把s交给sap2管
AutoPtr <S> sap3(new S); //也可以直接接管一个匿名的指针
AutoPtr <S> sap4 = new S; //编译不通过,关键字explicit起的作用
S s2; //这家伙来自栈,将自动释放
AutoPtr <S> sap5(&s2); //编译通过,但后果自负

001行构造sap时,调用的是默认构造函数(无入参),sap的_ptr成员被初始化为nullptr,

002行,调用sap->a,相当于执行“0->a”。执行结果不定

003行,在外部创建一个S的“堆对象”,

004行,通过sap2对它进行托管,因此在后面的代码中千万不鞥delete s。

005行,是一个好做法,只要有可能,就争取在创建自动指针的同时创建外部指针,并且令其成为一个匿名的对象(没有变量承载),避免引入重复产出一个对象的问题。

006行,sap4构造失败,原因是“explicit”关键字起了作用。尽管我们所模仿的auto_ptr允许此类操作,但这里不考虑将一个T*对象直接赋值给AutoPtr<T>对象功能(那会引入许多更复杂的要求)。

007行的s2是一个“栈对象”,所以它总是会被自动释放内存,将它托付给一个只晓得“我一定要负责干掉它”的所谓的“智能指针”,会酿成大错。

允许改变指向

当AutoPtr持有一个指针之后,如何释放呢?

先来为AutoPtr增加一个离婚的首先,函数名叫“release”。

template <typename T>
T* AutoPtr <T>::release() //放手
{//放手, release,返回裸指针,智能指针不再占有内存T* you_are_free_now = _ptr;_ptr = nullptr;return you_are_free_now;
}

注意,所谓“放手”,是将AutoPtr原来拥有的_ptr “归还”回去,这样可以方便“离婚”后的_ptr独立存在:

AutoPtr <int> ap(new int);//结合
int* tmp = ap.release();//分手,曾经的_ptr现在是陌生的“tmp”

接下来,是再婚手续,为了合法,会先强制离婚:

template <typename T>
T* AutoPtr <T>::reset(T* new_ptr) 
{//智能指针开始管理新的裸指针,返回旧的裸指针T* old_ptr = release();_ptr = new_ptr;//由来只闻新人笑return old_ptr;//有谁听过旧人哭,旧人回娘家
}

设计一个完整的智能指针,所要考虑的事情远不止以上那些,比如:

如何判断智能指针是一个空指针?

如果比较两个智能指针?

如何在智能指针之间赋值?

【课堂作业】AutoPtr的实现

(1)根据以上代码,整理出一份相对完整,实际可用的AutoPtr,并写出配套的试用例子。

(2)考虑所写的AutoPtr是否支持处理数组指针,比如“AutoPtr <int> ap(new int [5])”,如果要支持,应如何改进?

这篇关于《白话C++》第9章 泛型,Page847~849 AutoPtr 允许从外部指针构造的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/718554

相关文章

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.