IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 隐式的类类型转换 explicit学习 -> 正文阅读

[C++知识库]C++ 隐式的类类型转换 explicit学习

C++ primer 5e中练习7.48中

假定Sales_data的构造函数不是explicit的,则下述定义将执行什么样的操作?

string null_isbn("999");

Sales_data item1(null_isbn);

Sales_data item2("999999");

如果Sales_data的构造函数时explicit的,又会发生什么呢?

?https://github.com/pezy/CppPrimer/tree/master/ch07#exercise-748

这个答案没有任何问题,在评论区有人问:”?48题的item2,这个不是从字面值转为string,然后再转为Sales_data吗?执行了两次类型转换,为什么不报错??书上不是说了,编译器只会自动执行一步类型转换吗“

是不是执行了两次类型转换??

明显,这里并没有执行两次类型转换,而是一次类型转换+一次构造函数调用


/*情况 1 */
//相当于调用了参数为string的构造函数
string null_book = "999";
Sales_data item1(null_book);

//将字符串字面值转为string后再调用对应的构造函数
Sales_data item2("999"); 

//------------------------------------------------------------------

/*情况 2  无explicit */
Sales_data item3;
//错误,需要转换两次--字符串字面值转string,string隐式调用(转换)Sales_data
item3.combine("999"); 

//正确,隐式调用构造函数,然后传入combine
item3.combine(string("999")); 

//正确,将字符串字面值转换为string后调用对应的构造函数再传入combine
item3.combine(Sales_data("999")); 

//------------------------------------------------------------------

/*情况 3  有explicit */
Sales_data item4;

//错误,同item3.combine("999");
item4.combine("999"); 

//错误,无法隐式调用构造函数
item4.combine(string("999"));  

//正确,字符串字面值转为string后调用构造函数再传入combine
item4.combine(Sales_data("999")); 

附完整代码进行测试:

#include <iostream>
#include <string>

//为方便测试,将类定义整合进一个cpp文件中
struct Sales_data {

    //Sales_data() = default;

  //构造函数1
    Sales_data(const std::string& s, unsigned n, double p)
        : bookNo(s), units_sold(n), revenue(n * p){ std::cout<<"1,2,3"<<std::endl; }
  //构造函数2
    Sales_data(const std::string &s):Sales_data(s,0,0) { std::cout<<"1"<<std::endl;}
    //explicit Sales_data(const std::string &s)::Sales_data(s,0,0) { std::cout<<"1"<<std::endl; }
  //构造函数3
    std::istream& read(std::istream &,Sales_data&);  //read的声明位置并无影响
    Sales_data(std::istream &is):Sales_data() { std::cout<<"istream"<<std::endl; read(is, *this); }

  //构造函数4
    Sales_data():Sales_data("",0,0) { std::cout<<"()"<<std::endl;; };

    std::string isbn() const { return bookNo; };
    Sales_data& combine(const Sales_data&);

    std::string bookNo = "";
    unsigned units_sold = 0;
    double revenue = 0.0;
};

// nonmember functions
std::istream& Sales_data::read(std::istream& is, Sales_data& item)
{
    double price = 0;
    is >> item.bookNo >> item.units_sold >> price;
    item.revenue = price * item.units_sold;
    return is;
}

std::ostream& print(std::ostream& os, const Sales_data& item)
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue;
    return os;
}

Sales_data add(const Sales_data& lhs, const Sales_data& rhs)
{
    Sales_data sum = lhs;
    sum.combine(rhs);
    return sum;
}



Sales_data& Sales_data::combine(const Sales_data& rhs)
{
    units_sold += rhs.units_sold;
    revenue += rhs.revenue;
    return *this;
}

int main()
{

    //情况 1
std::string null_book = "999";
Sales_data item1(null_book); //相当于调用了参数为string的构造函数
Sales_data item2("999"); //将字符串字面值转为string后再调用对应的构造函数

//情况 2  无explicit
Sales_data item3;
item3.combine("999"); //错误,需要转换两次
item3.combine(std::string("999")); //正确,隐式调用构造函数,然后传入combine
item3.combine(Sales_data("999")); //正确,将字符串字面值转换为string后调用对应的构造函数再传入combine

//情况 3  有explicit
Sales_data item4;
item4.combine("999"); //错误,同item3.combine("999");
item4.combine(std::string("999"));  //错误,无法隐式调用构造函数
item4.combine(Sales_data("999")); //正确,字符串字面值转为string后调用构造函数再传入combine


  return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 11:52:27  更:2021-08-19 11:53:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 13:00:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码