当前位置: 首页 > java >正文

std::optional 类是个啥?


author: hjjdebug
date: 2025年 04月 29日 星期二 17:30:07 CST
description: std::optional 类是个啥?


文章目录

  • 1. std::optional 是一个类. 而且还是一个模板类.
  • 2. std::optional 封装了什么?
  • 3. 封装这个数据干什么?
  • 4. 就干这点事还用得着设计一个类吗?
  • 5.一个简单的实例

1. std::optional 是一个类. 而且还是一个模板类.

很玄,模板类代表可以形成任意数据类型的类. 在编译时根据调用才形成具体的类.
类是什么?类是一种结构,它的3个要点是数据封装,继承和多态. 类的实例化叫对象

2. std::optional 封装了什么?

封装了你传来的一个类型数据T, 它没有继承谁,也没有多态性,相对简单了些.

3. 封装这个数据干什么?

封装这个数据是为了安全性, 因为这个数据有可能是无效值,有可能是正常值.

4. 就干这点事还用得着设计一个类吗?

比方说整数, 我让-1定为无效值,其它是有效值.
比方说字符串,我让空定为无效值,其它为有效值.
其它的类型,有其它定义有效无效的方法…

可是一个吹毛求疵的人出现了, 它说,你不能把-1当成无效值,可能我就有一个数是-1.
空字符串也不能代表它无效. 可能它是有效的,它只是空而已.

于是std::optional类中定义了一个bool valid变量, (这个是假想的,逻辑上是这样,实际上可以有多种形式)
当valid为真时,表示有值.
当valid 为假时,就是没有值,这就是它的核心概念之一.
另一个核心概念就是把你传来的值保存起来, 保存方式是值保存.会有内存copy
然后你可以通过接口访问到它的值

它的好处是合法性判断实现了类型统一.
不用判断整数是否是-1,字符串是否为空,而是改为统一判断optonal对象是否有值. obj.has_value();

它为什么能统一? 因为它用类封装了.(实际是用类封装了valid变量)
我看了一眼它的实现代码, 就这么点功能竟洋洋洒洒的写了1200多行代码,表示看不懂,
类里套类,环环相套,估计不下几十种类,几百个函数.
而且其模板函数对于ctags 工具都分析不了哪是函数,哪是声明
不知道是不是c++的悲哀,所以还是着重使用,能理解就可以了.

5.一个简单的实例

$ cat main.cpp 
#include <iostream>
#include <optional>
using namespace std; 
void print_it(std::optional<int> obj)
{  //当has_value 为真时, value值才有意义, 为假,value值无意义,这就是optional对象的核心cout<<"has value:"<<obj.has_value()<<" value:"<<*obj<<endl;
}
int main() {std::optional<int> number;print_it(number);number=10;print_it(number);number=-1;print_it(number);number=std::nullopt;print_it(number);return 0;
}

执行代码:

./optional_test
has value:0 value:0
has value:1 value:10
has value:1 value:-1
has value:0 value:-1

打印时为什么要用

*obj

答: obj 是std::optional 对象, "*obj "是对obj的一种解引用. 其中*号肯定是被重载过的,
就是说另定义了*运算符的行为, 使其返回值是它保留的整数值
obj.has_value() 用来返回该对象当前的值是否有效.
看一看gdb中打印的尊容吧. 这就是对象包含的内容.

p numbernumber = std::optional<int> [no contained value]
p numbernumber = std::optional<int> = {[contained value] = 10
}
p numbernumber = std::optional<int> = {[contained value] = -1 
}
p numbernumber = std::optional<int> [no contained value]
http://www.xdnf.cn/news/3070.html

相关文章:

  • esp32将partitions.csv文件启用到工程项目中的配置
  • antd pro4 升级 antd5
  • 深入解析:实现一个详细的日志过滤器(LogFilter)
  • 2025年渗透测试面试题总结-拷打题库25(题目+回答)
  • 30天通过软考高项-第一天
  • 刀客doc:小红书商业技术负责人苍响离职
  • 信息系统项目管理师——第10章 项目进度管理 笔记
  • 解决Ollama run qwen3:32b: Error: unable to load model问题
  • 阵列麦克风降噪原理
  • 记录一个单独读取evt.bdf的方法
  • 头歌java课程实验(文件操作)
  • 【CF】Day46——Codeforces Round 967 (Div. 2) B
  • 2025年高级Java后端面试题:最新技术体系深度解析
  • java发送邮件
  • 运行不会存储上一次的命令;运行命令不保存历史记录
  • 算法备案类型解析:如何判断你的算法属于哪种类型?
  • conda添加新python版本环境,如何激活和销毁
  • 深入理解 Web Service:原理、组件与核心技术详解
  • c++ 内部类
  • linux使用亚马逊aws-sdk-cpp
  • 适合五一劳动节的SVG模版
  • C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 15)
  • Windows多网卡设置路由冲突的解决
  • 程序员如何用AI工具实现“快速验证原型”
  • Rational Rose显示工具栏及添加工具栏中想要的工具(小人图标,用例图标)
  • 浏览器限制了cookie数量怎么办
  • Educational Codeforces Round 178 (Rated for Div. 2)
  • 什么是单臂路由
  • 制作JDK17 arm64基础镜像,解决字体安装问题
  • 使用Python将大文件夹中的文件分成文件数量相等的小文件夹