Cherno C++系列笔记12——P40~P41 隐式转换与explicit关键字、运算符及其重载

本文主要是介绍Cherno C++系列笔记12——P40~P41 隐式转换与explicit关键字、运算符及其重载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1.P40 隐式转换于explicit关键字
    • 1.1.隐式类型转换(隐式构造函数)
    • 1.2.explicit关键字禁止隐式类型转换
  • 2.P41 运算符及其重载

1.P40 隐式转换于explicit关键字

参考:视频 笔记

1.1.隐式类型转换(隐式构造函数)

隐式转换的意思是不会明确的告诉编译器要怎么做,像是编译器通过上下文自动推导要做的事情。

C++允许编译器对代码执行一次隐式转换,在两个类型之间C++允许进行隐式转换,而不需要用cast做强制转换,类型转换是将数据类型转换到另一个类型的过程。

如下代码所示,将a赋值为herno,b直接等于22(Java,C#等其他语言不行)。这被称为隐式转换,或者叫隐式构造函数。它隐式地将22转换成一个Entity并构造出一个Entity,因为有一个Entity的构造函数接受一个整数的参数。另一个构造函数接受的字符串name是”Cherno”作为参数。

由于Entity这个类有两个构造函数,分别传入stirng和int作为形参,所以就可以直接写Entity a = "Cherno"; Entity b = 22;,使用string和int类型的数据直接构造Entity对象,这里C++编译器就进行了一次隐式类型转换。

ps:注意在VS2019 MSVC C++14环境下Entity a = “Cherno”;会报错,因为字符串字面量"Cherno"在编译器中认为是const char*,而Entity类的构造函数形参为string类,所以这里存在const char* -> string -> Entity两次类型转化,而C++只允许一次隐式类型转换。

#include<iostream>
#include<string>class Entity
{
private:std::string  m_Name;int m_Age;
public:Entity(const std::string& name):m_Name(name), m_Age(-1) {}Entity(int age):m_Name("Unknown"), m_Age(age) {}
};int main()
{// 1.正常的写法,不包含隐式转换//Entity a("Cherno");//Entity b(22);//Entity a = Entity("Cherno");//Entity b = Entity(22);// 2.使用隐式转换的写法Entity a = "Cherno";Entity b = 22;std::cin.get();
}

同样的隐式类型转换还可以发生在函数参数传递的过程中:创建一个PrintEnti函数用来做打印,参数是entity。我们可以直接调用这个函数,参数为22。因为C++认为22可以转换成一个Entity(隐式转换),可以调用这个构造函数,22是创建Entity的唯一参数。PrintEntity(“Cherno”);则会报错,因为"Cherno"不是std::string而是char数组。所以C++需要2次转换,一个从const char数组到string,一个从stringEntity。但因为只允许做一次隐式转换,所以必须把它包装在一共构造函数中,或者包装在一个Entity对象中(隐式地将这个字符串转换为std:string标准字符串,然后推入Entity构造函数)。

void PrintEntity(const Entity& entity)
{// Printing
}int main()
{PrintEntity(22); PrintEntity("Cherno"); // 报错PrintEntity((std::string)"Cherno");  // 编译通过PrintEntity(Entity("Cherno")); std::cin.get();
}

1.2.explicit关键字禁止隐式类型转换

explicit与隐式转换有关,因为explicit禁用这个隐式转换的功能,explicit关键字放在构造函数前面表示没有隐式的转换。如果要使用整数构造这个Entity对象,则必须显式调用此构造函数。
  
把explicit放在int age构造函数前面,则会发现PrintEntity(22); 和Entity b = 22;都失败了。在这里插入图片描述
若把explicit放在第一个构造函数前面,第25行同样会失败。但是24行会成功,因为它实际上调用了构造函数。

在这里插入图片描述

2.P41 运算符及其重载

参考:视频 笔记

运算符重载这个也比较基础,没有什么新的内容。其中重载<<流运算符的例子可以看一下,输入和输出都是std::ostream的引用&是为了实现<<流运算符的链式法则,这个在《21天学通C++》中有讲解。

#include<iostream>
#include<string>struct Vector2
{float x, y;Vector2(float x, float y):x(x), y(y) {}Vector2 Add(const Vector2& other) const{return Vector2(x + other.x, y + other.y);}Vector2 Multiply(const Vector2& other) const{return Vector2(x * other.x, y * other.y);}Vector2 operator+(const Vector2& other) const{return Add(other);}Vector2 operator*(const Vector2& other) const{return Multiply(other);}
};// 重载<<
std::ostream& operator<<(std::ostream& stream, const Vector2& other)
{stream << other.x << "," << other.y;return stream;
}int main()
{Vector2 position(4.0f, 4.0f);Vector2 speed(0.5f, 1.5f);Vector2 powerup(1.1f, 1.1f);Vector2 result2 = position + speed * powerup;std::cout << result2 << std::endl;std::cin.get();
}

在使用std::cout我们会用到左移运算符,它接受2个参数。一个是输出流cout,另一个是vector2。我们需要在vector2类的外面将<<运算符重载。它和vector2没有任何关系,我们是在cout中重载。我们写上std::ostream&输出流,是一个引用。这是我们需要重载符号的最初定义,然后写一个operator加上左移运算符,然后需要一个对现有流的引用,传入const vector2通过引用传递。

这篇关于Cherno C++系列笔记12——P40~P41 隐式转换与explicit关键字、运算符及其重载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/386011

相关文章

Python3脚本实现Excel与TXT的智能转换

《Python3脚本实现Excel与TXT的智能转换》在数据处理的日常工作中,我们经常需要将Excel中的结构化数据转换为其他格式,本文将使用Python3实现Excel与TXT的智能转换,需要的可以... 目录场景应用:为什么需要这种转换技术解析:代码实现详解核心代码展示改进点说明实战演练:从Excel到

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型