首页 > 其他分享 >union学习

union学习

时间:2023-10-03 16:35:19浏览次数:29  
标签:std string union sval 学习 tok Token STR

#include <iostream>
#include <string>

class Token {
public:
  Token() : tok(INT), ival(0) {}
  ~Token() {
    if (tok == STR) {
      sval.~basic_string();  // 联合体中编译器不会自动调用析构函数
    }
  }

  Token& operator=(int i) {
    if (tok == STR) {
      sval.~basic_string();
    }
    ival = i;
    tok = INT;
    return *this;
  }

  Token& operator=(char c) {
    if (tok == STR) {
      sval.~basic_string();
    }
    ival = c;
    tok = CHAR;
    return *this;
  }

  Token& operator=(double d) {
    if (tok == STR) {
      sval.~basic_string();
    }
    ival = d;
    tok = DBL;
    return *this;
  }

  Token& operator=(const std::string& s) {
    if (tok == STR) {
      sval = s;
    }
    else {
      // 定位 new,在已经分配的内存位置上构造一个对象,而不是在堆上分配新的内存
      // 在 sval 的当前位置上构造一个新的 std::string 对象,并使用 s 来初始化它
      new(&sval) std::string(s);
    }
    tok = STR;
    return *this;
  }

  // 赋值运算符(为已存在的对象赋值时被调用)
  Token& operator=(const Token& t) {
    if (tok == STR && t.tok != STR) {
      sval.~basic_string();
    }
    if (tok == STR && t.tok == STR) {
      sval = t.sval;
    }
    else {
      copyUnion(t);
    }
    tok = t.tok;
    return *this;
  }

private:
  enum {INT, CHAR, DBL, STR} tok;
  union {
    char cval;
    int ival;
    double dval;
    std::string sval;
  };
  void copyUnion(const Token& t) {
    switch (t.tok)
    {
    case INT:
      ival = t.ival; break;
    case CHAR:
      cval = t.cval; break;
    case DBL:
      dval = t.dval; break;
    case STR:
      new(&sval) std::string(t.sval); break;
    }
  }
};

int main() {
  // 创建 Token 对象
  Token t1, t2, t3, t4, t5;

  // 使用赋值运算符为对象赋值
  t1 = 42;               // int
  t2 = 'a';             // char
  t3 = 3.14;            // double
  t4 = std::string("Hello, World!");  // std::string

  // 输出结果
  std::cout << "t1 assigned with int: 42" << std::endl;
  std::cout << "t2 assigned with char: 'a'" << std::endl;
  std::cout << "t3 assigned with double: 3.14" << std::endl;
  std::cout << "t4 assigned with string: \"Hello, World!\"" << std::endl;

  // 使用拷贝赋值运算符
  t5 = t4;
  std::cout << "t5 copied from t4 (which contains a string)" << std::endl;

  // 为已包含字符串的 Token 对象赋值一个 int
  t4 = 100;
  std::cout << "t4 reassigned with int: 100" << std::endl;

  return 0;
}

标签:std,string,union,sval,学习,tok,Token,STR
From: https://www.cnblogs.com/hacker-dvd/p/17741245.html

相关文章

  • HTML学习笔记
    一、标签在html中每个标签都是成对存在例如:<html> <body>HelloCSDN!</body></html>二、属性写在<>里面的用来定义功能的作用例如:<h2style="background-clolor:red;text-align:center">Helloworld!</h2&......
  • 列表与字典学习笔记
    python中要想用对象做某种处理,需要这个对象的名字(变量名),然后是一个点,再后面是要对对象做的操作。如要向friends列表zhui追加一个元素,就要写成:friends.append(something)列表:列表可以包含python能存储的任何类型的数据(数字,字符串、对象,甚至其他列表)列表中的元素并不要求元素是......
  • MySQL学习(2)什么是InnoDB数据页
    前言什么是InnoDB页MySQL服务器中负责读写数据的是存储引擎,InnoDB是一种常用的,将表数据存储在磁盘中的存储引擎。在实际操作中,MySQL将磁盘中的数据加载到内存中,若是需要处理写入或修改,则把内存中的数据刷新到磁盘。什么是行格式数据是以记录为单位在表中存储的,每一......
  • MySQL学习(1)MySQL程序有什么
    认识MySQLMySQL的客户端/服务器MySQL服务器是运行在计算机中,直接与要存储的数据打交道的程序,多个客户端程序可以连接到这个服务器程序,向服务器发送增删改查的请求,然后服务器程序根这些请求,对存储的数据进行相应的处理。MySQL社区版下载地址:https://dev.mysql.com/downloads/......
  • vue 学习笔记
    https://www.bilibili.com/video/BV13m4y1Y7MD安装vuecli1安装 node.js要求node.js12+版本, https://nodejs.org/zh-cn 首页下载安装lts版本,如果已安装就覆盖安装vscode终端或cmd中输入npm--vesion  node--v可以查看是否安装成功npm(nodepackagemanager):no......
  • 高级系统架构师学习(十)项目管理、数学与经济管理、知识产权与标准化
    一、项目管理立项管理一盈亏平衡管理销售额=固定成本+可变成本+税费+利润【正常情况下】销售额=固定成本+可变成本+税费【盈亏平衡时】进度管理【重点!!!!!】定义:为了确保项目按期完成所需要的管理过程。过程工作分解结构【WBS】WBS分解的基......
  • MySQL学习目录
    MySQL学习目录第一章-数据库基础知识第二章-MySQL语言基础第三章-数据定义第四章-数据更新第五章-查询数据第六章-数据视图第七章-索引第八章-数据库编程第九章-数据安全第十章-使用Python操作MySQL数据库......
  • openGauss学习笔记-87 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-M
    openGauss学习笔记-87openGauss数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用简单概述使用MOT非常简单,以下几个小节将会进行描述。openGauss允许应用程序使用MOT和基于标准磁盘的表。MOT适用于最活跃、高竞争和对吞吐量敏感的应用程序表,也可用于所有应用程序的表。......
  • SQLite学习笔记——创建数据库和SELECT,INSERT语句
    SQLite创建数据库我们可以直接使用sqlite3DatabaseName.db来创建数据库,这时候我们就会发现同一目录下出现了对应的.db文件或者我们可以先启动sqlite3然后在里面使用点命令.openDatabaseName.db来创建数据库,如果已经存在对应的数据库,那么我们默认就会打开该数据库。......
  • 通过linux0.11学习操作系统原理--Apple的学习笔记
    一,前言最近在断断续续的看linux0.11的源码介绍,主要是了解linux操作系统的原理,之前已经了解了进程的切换主要是cpu上下文切换+虚拟内存切换。今天我主要看了下改开始linux启动的进程0,1,2。二,分析先回顾了之前的问题LDT和GDT的区别?   GDT用作内核态的代码和数据段,LDT用作用户进......