一:背景

最近发现 C++ 中的类型初始化操作,没有 {} 运算符搞不定的,蛮有意思,今天我们就来逐一列一下各自的用法以及汇编展现,本来想分为 值类型引用类型 两大块,但发现在 C++ 中没这种说法,默认都是 值类型

二:各种玩法一览

1. int 上的初始化

首先看一下代码:


int main()
{
int i = { 10 };
int j{ 10 }; printf("i=%d, j=%d", i, j);
}

相比C#来说,不带 = 的写法感觉还是怪怪的。。。 接下来看下对应的汇编代码。


int i = { 10 };
00021825 mov dword ptr [ebp-8],0Ah
int j{ 10 };
0002182C mov dword ptr [ebp-14h],0Ah

从汇编代码看,就是一个简单的 栈赋值 ,所以在 int 上用 {} 完全没必要,太伤键盘了。

2. 数组的初始化

继续看例子。


int main()
{
int num[] = { 10,11,12 };
}

这种写法中规中矩,基本上 C 系列的语言都这样,对于玩 C# 的我来说,不陌生。。。 不过人家默认是值类型,C# 是引用类型,从汇编代码中也能看的出来。


int num[] = { 10,11,12 };
009C1E95 mov dword ptr [ebp-10h],0Ah
009C1E9C mov dword ptr [ebp-0Ch],0Bh
009C1EA3 mov dword ptr [ebp-8],0Ch

3. 结构体的初始化

结构体大家都很熟悉,直接上代码了。


typedef struct _Point
{
int x;
int y;
} Point; int main()
{
Point point = { 10,20 };
}

接下来看一下汇编代码。


Point point = { 10,20 };
00481825 mov dword ptr [ebp-0Ch],0Ah
0048182C mov dword ptr [ebp-8],14h

可以看到,其实也是一组简单的赋值操作,很方便。

4. 类的初始化

方便讲述,先上代码:


class Location {
private:
int x;
int y;
int z;
public:
Location(int x, int y, int z) :x(x), y(y), z(z) {
}
}; int main()
{
Location location = { 10,11,12 };
}

接下来看下汇编代码,是不是调用了 Location 的构造函数。


Location location = { 10,11,12 };
008D183F push 0Ch
008D1841 push 0Bh
008D1843 push 0Ah
008D1845 lea ecx,[ebp-14h]
008D1848 call Location::Location (08D13A7h)

可以看到确实调用了 构造函数,那个 ecx 就是 location 的 this 指针。

5. initializer_list 模板类

C++ 中的 initializer_list 类可以接收 {} 初始化语法作为初始化操作,这个有一点像 C# 的 param 可选参数,接下来把上例的中构造函数改成 initializer_list 来接收,代码如下:


class Location {
public:
int x;
int y;
int z;
public:
Location(initializer_list<int> list) { x = *(const_cast<int*>(list.begin()));
y = *(const_cast<int*>(list.begin() + 1));
z = *(const_cast<int*>(list.begin() + 2));
}
}; int main()
{
Location loc = { 10,11,12 };
printf("loc.x=%d,loc.y=%d,loc.z=%d", loc.x, loc.y, loc.z);
}

接下来看下汇编代码。


Location loc = { 10,11,12 };
00B9518F mov dword ptr [ebp-0F8h],0Ah
00B95199 mov dword ptr [ebp-0F4h],0Bh
00B951A3 mov dword ptr [ebp-0F0h],0Ch
00B951AD lea eax,[ebp-0ECh]
00B951B3 push eax
00B951B4 lea ecx,[ebp-0F8h]
00B951BA push ecx
00B951BB lea ecx,[ebp-0E4h]
00B951C1 call std::initializer_list<int>::initializer_list<int> (0B913C5h)
00B951C6 mov edx,dword ptr [eax+4]
00B951C9 push edx
00B951CA mov eax,dword ptr [eax]
00B951CC push eax
00B951CD lea ecx,[loc]
00B951D0 call Location::Location (0B913ACh)

从汇编代码看,它首先做了 initializer_list 的初始化操作,然后将弄好的集合丢到 Location 构造函数中,反转过来大概就是这样。


int main()
{
initializer_list<int> list = { 10,11,12 }; Location loc = { list }; printf("output: loc.x=%d,loc.y=%d,loc.z=%d", loc.x, loc.y, loc.z);
}

哈哈,是不是感觉 {} 在初始化方面无所不能,好了,本篇就聊到这里了。

聊聊 C++ 大一统的初始化运算符 {}的更多相关文章

  1. 使用栈Stack对整数数值的运算表达式字符串进行运算C#

    这里如果对于形如字符串“((6+((7+8)-9)*9+8/2)-3)/2”的运算表达式进行运算.接触过此类的同学知道这种存在着运算符优先级的表达式,不能直接从左到右进行运算,我们使用OperandS ...

  2. 三道题(关于虚表指针位置/合成64位ID/利用栈实现四则运算)

    第一题 C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的.请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面.  第二题 在游戏中所有物品的实例 ...

  3. c/c++ 表达式求值

    表达式求值 [问题描述] 一个算术表达式是由操作数(operand).运算符(operator)和界限符(delimiter)组成的.假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括 ...

  4. nyoj(表达式求值)

    描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2 ...

  5. C语言 | 计算器实现(中缀表示法/后缀表示法)

    ———————————————————————————————————————————— 实现原理: 每个操作数都被依次压入栈中,当一个运算符到达时,从栈中弹出相应数目的操作数(对于二元运算符来说是两 ...

  6. 计算机基础——Java笔记一

            电子管-晶体管 摩尔定律 18个月变一次       贝尔实验室 C语言是基础.芯片领域软件领域 机器语言 ——汇编语言——高级语言 (面向过程,面向对象)   基本的逻辑怎么用代码实 ...

  7. 结对项目:四则运算(C语言)

    github地址:https://github.com/nilonger/arithmetic 结对伙伴:杨锐龙+黄海钊 一.项目要求 1.1 题目:实现一个自动生成小学四则运算题目的命令行程序(也可 ...

  8. TensorFlow神经网络集成方案

    TensorFlow神经网络集成方案 创造张力流create_tensorflow_neuropod 将TensorFlow模型打包为neuropod包. create_tensorflow_neur ...

  9. MinIO对接k8s使用

    文档地址:https://github.com/minio/operator/blob/master/README.md https://docs.min.io/minio/k8s/deploymen ...

随机推荐

  1. Spring (IOC)配置

    就是这个东西,里面的不同标签,所代表的不同含义 beans  里面有很多的bean  ,每一个bean都是容器里面的一个对象 1.别名alias  (另外的一个名字) XML <alias na ...

  2. ReadWriteLock 接口详解

    ReadWriteLock 接口详解 这是本人阅读ReadWriteLock接口源码的注释后,写出的一篇知识分享博客 读写锁的成分是什么? 读锁 Lock readLock(); 只要没有写锁,读锁可 ...

  3. TCP 协议灵魂 12 问,巩固你的网路底层基础!

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一 ...

  4. MySQL 高频面试题,都在这了

    点击上方"开源Linux",选择"设为星标"回复"学习"获取独家整理的学习资料! 前言 本文主要受众为开发人员,所以不涉及到MySQL的服务 ...

  5. SSH 证书登录教程

    开源Linux 专注分享开源技术知识 SSH 是服务器登录工具,提供密码登录和密钥登录. 但是,SSH 还有第三种登录方法,那就是证书登录.很多情况下,它是更合理.更安全的登录方法,本文就介绍这种登录 ...

  6. ThreadLocal夺命11连问

    前言 前一段时间,有同事使用ThreadLocal踩坑了,正好引起了我的兴趣. 所以近期,我抽空把ThreadLocal的源码再研究了一下,越看越有意思,发现里面的东西还真不少. 我把精华浓缩了一下, ...

  7. CF1485E Move and Swap

    题意:Move and Swap 很好的题呢 n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次: 1.R点跳到子树内 2.B点跳到下一层的任 ...

  8. Java开发学习(二)----IOC、DI入门案例

    一.IOC入门案例 1.1 思路分析 (1)Spring是使用容器来管理bean对象的,那么管什么? 主要管理项目中所使用到的类对象,比如(Service和Dao) (2)如何将被管理的对象告知IOC ...

  9. iPhone x 的区别

    最近入手两台iPhone x, 均从官网购买,两台分别是2017年和2018年生产,对比了一下,两台还有是一些差别: 首先苹果X使用起来还是非常爽的,没有HOME键,明显比按HOME键方便,因为按HO ...

  10. 一文带你搞懂 JWT 常见概念 & 优缺点

    在 JWT 基本概念详解这篇文章中,我介绍了: 什么是 JWT? JWT 由哪些部分组成? 如何基于 JWT 进行身份验证? JWT 如何防止 Token 被篡改? 如何加强 JWT 的安全性? 这篇 ...