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

相关文章

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa