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]