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

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)