聊聊 C++ 大一统的初始化运算符 {}
一:背景
最近发现 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++ 大一统的初始化运算符 {}的更多相关文章
- 使用栈Stack对整数数值的运算表达式字符串进行运算C#
这里如果对于形如字符串“((6+((7+8)-9)*9+8/2)-3)/2”的运算表达式进行运算.接触过此类的同学知道这种存在着运算符优先级的表达式,不能直接从左到右进行运算,我们使用OperandS ...
- 三道题(关于虚表指针位置/合成64位ID/利用栈实现四则运算)
第一题 C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的.请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面. 第二题 在游戏中所有物品的实例 ...
- c/c++ 表达式求值
表达式求值 [问题描述] 一个算术表达式是由操作数(operand).运算符(operator)和界限符(delimiter)组成的.假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括 ...
- nyoj(表达式求值)
描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2 ...
- C语言 | 计算器实现(中缀表示法/后缀表示法)
———————————————————————————————————————————— 实现原理: 每个操作数都被依次压入栈中,当一个运算符到达时,从栈中弹出相应数目的操作数(对于二元运算符来说是两 ...
- 计算机基础——Java笔记一
电子管-晶体管 摩尔定律 18个月变一次 贝尔实验室 C语言是基础.芯片领域软件领域 机器语言 ——汇编语言——高级语言 (面向过程,面向对象) 基本的逻辑怎么用代码实 ...
- 结对项目:四则运算(C语言)
github地址:https://github.com/nilonger/arithmetic 结对伙伴:杨锐龙+黄海钊 一.项目要求 1.1 题目:实现一个自动生成小学四则运算题目的命令行程序(也可 ...
- TensorFlow神经网络集成方案
TensorFlow神经网络集成方案 创造张力流create_tensorflow_neuropod 将TensorFlow模型打包为neuropod包. create_tensorflow_neur ...
- MinIO对接k8s使用
文档地址:https://github.com/minio/operator/blob/master/README.md https://docs.min.io/minio/k8s/deploymen ...
随机推荐
- Spring (IOC)配置
就是这个东西,里面的不同标签,所代表的不同含义 beans 里面有很多的bean ,每一个bean都是容器里面的一个对象 1.别名alias (另外的一个名字) XML <alias na ...
- ReadWriteLock 接口详解
ReadWriteLock 接口详解 这是本人阅读ReadWriteLock接口源码的注释后,写出的一篇知识分享博客 读写锁的成分是什么? 读锁 Lock readLock(); 只要没有写锁,读锁可 ...
- TCP 协议灵魂 12 问,巩固你的网路底层基础!
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一 ...
- MySQL 高频面试题,都在这了
点击上方"开源Linux",选择"设为星标"回复"学习"获取独家整理的学习资料! 前言 本文主要受众为开发人员,所以不涉及到MySQL的服务 ...
- SSH 证书登录教程
开源Linux 专注分享开源技术知识 SSH 是服务器登录工具,提供密码登录和密钥登录. 但是,SSH 还有第三种登录方法,那就是证书登录.很多情况下,它是更合理.更安全的登录方法,本文就介绍这种登录 ...
- ThreadLocal夺命11连问
前言 前一段时间,有同事使用ThreadLocal踩坑了,正好引起了我的兴趣. 所以近期,我抽空把ThreadLocal的源码再研究了一下,越看越有意思,发现里面的东西还真不少. 我把精华浓缩了一下, ...
- CF1485E Move and Swap
题意:Move and Swap 很好的题呢 n个节点的树,根为1,所有叶子的深度都是D,一开始根节点上有两个颜色分别微R,B的球,你执行下列操作D-1次: 1.R点跳到子树内 2.B点跳到下一层的任 ...
- Java开发学习(二)----IOC、DI入门案例
一.IOC入门案例 1.1 思路分析 (1)Spring是使用容器来管理bean对象的,那么管什么? 主要管理项目中所使用到的类对象,比如(Service和Dao) (2)如何将被管理的对象告知IOC ...
- iPhone x 的区别
最近入手两台iPhone x, 均从官网购买,两台分别是2017年和2018年生产,对比了一下,两台还有是一些差别: 首先苹果X使用起来还是非常爽的,没有HOME键,明显比按HOME键方便,因为按HO ...
- 一文带你搞懂 JWT 常见概念 & 优缺点
在 JWT 基本概念详解这篇文章中,我介绍了: 什么是 JWT? JWT 由哪些部分组成? 如何基于 JWT 进行身份验证? JWT 如何防止 Token 被篡改? 如何加强 JWT 的安全性? 这篇 ...