侯捷C++高级编程(下)

对于1个类要么像指针要么像函数

主题1:转换函数

转换函数

/** 1. 转换函数没有返回类型* 2. 转换函数一般需要加上const*/
class Fraction
{
public:Fraction(int num,int den=1):m(num),n(den){cout<<"Fraction(int num,int den=1): m/n = "<< m/n<<endl;}operator double()const{cout<<"调用转换函数double():"<<(double)( m/n )<<endl;return (double)( m/n );}
private:int m;int n;
};
int main(int argc, char** argv)
{Fraction f(8,2);double d = 5 + f;/** 首先 4* */
//    Fraction d = f + 4;cout<<d<<endl;/** 输出结果:* Fraction(int num,int den=1):m/n = 4* 调用转换函数double()* 8* 分析:f(8,2): 首先调用构造函数* 然后;5 + f 中的f调用转换函数转换为double*/
}

non-explict-one-argument ctor

class Fraction
{
public:Fraction(int num,int den=1):m(num),n(den){cout<<"Fraction(int num,int den=1): m/n = "<< m/n<<endl;}Fraction operator+(const Fraction &f){cout<<"调用operator+()函数"<<endl;return Fraction(m+f.m,n+f.n);}
private:int m;int n;
};
int main(int argc, char** argv)
{Fraction f(8,2);Fraction d1 = f+5;// === f.operator+(5);/** 首先f+5中的5调用构造函数Fraction(int num,int den=1)* 然后调用operator+()函数*/
}

注意:提供默认值的构造函数可以将一种类中的为提供默认值的属性类型转换为该类类型---即将一种类型转化为本类类型 operaor double() --- 则是将本类型转化为double类型,两者转换方向刚好相反;但是我们一般所说的转换函数是后一种类型;
ambiguous error

class Fraction
{
public:Fraction(int num,int den=1):m(num),n(den){cout<<"Fraction(int num,int den=1): m/n = "<< m/n<<endl;}operator double()const{cout<<"调用转换函数double():"<<(double)( m/n )<<endl;return (double)( m/n );}Fraction operator+(const Fraction &f){cout<<"调用operator+()函数"<<endl;return Fraction(m+f.m,n+f.n);}
private:int m;int n;
};
Fraction operator+(int a,const Fraction &b)   
{
//解决5+f的问题
}
int main(int argc, char** argv)
{Fraction f(8,2);Fraction d1 = f+5;// Use of overloaded operator '+' is ambiguous (with operand types 'Fraction' and 'int')Fraction d1 = 5+f;
}

explict的使用:一般用在构造函数前面,表示此构造函数只能用于构造不能用于其他目的
explicit Fraction(int num,int den=1):m(num),n(den)
Fraction d1 = f+5;// error
但是仍然会出现:error: conversion from ‘double’ to non-scalar type ‘Fraction’ requested
解释:
f+5中首先由于在构造函数前面加上了explict所以不会ambiguous,f首先转换为double记为a,然后执行a+5后产生一个double记为c,但是c不能转化为Fraction,因为explict

:
Fraction operator+(int a,const Fraction &b)
{
//解决5+f的问题
}
是否可以成员函数实现,是否是下面的

class Fraction
{friend  Fraction operator+(int a,const Fraction &f){;} //注意这不是Fraction的成员函数,这个是全局函数。只不过在Fraction中声明为友元函数之后直接实现了。
}
//这里的5+f的实现利用friend成员函数没有this指针的特点

关于友元函数

  1. 友元函数没有this指针
  2. 因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。
  3. 友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友
    友元函数的分类:
    根据这个函数的来源不同,可以分为三种方法:
    普通函数友元函数:
    目的:使普通函数能够访问类的友元
    语法:
    声明: friend + 普通函数声明
    实现位置:可以在类外或类中
    实现代码:与普通函数相同
    调用:类似普通函数,直接调用
class INTEGER{friend void Print(const INTEGER& obj);//声明友元函数};void Print(const INTEGER& obj){//函数体}void main(){INTEGER obj;Print(obj);//直接调用}

类Y的所有成员函数都为类X友元函数—友元类
目的:使用单个声明使Y类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类Y的对象可以具有类X和类Y的功能。
语法:
声明位置:公有私有均可,常写为私有(把类看成一个变量)
声明: friend + 类名(不是对象哦)

class girl;class boy{public:void disp(girl &);};void boy::disp(girl &x) //函数disp()为类boy的成员函数,也是类girl的友元函数{cout<<"girl's name is:"<<x.name<<",age:"<<x.age<<endl;//借助友元,在boy的成员函数disp中,借助girl的对象,直接访问girl的私有变量}class girl{privatechar *name;int age;friend boy; //声明类boy是类girl的友元};

类Y的一个成员函数为类X的友元函数
目的:使类Y的一个成员函数成为类X的友元,具体而言:在类Y的这个成员函数中,借助参数X,可以直接以X的私有变量
语法:
声明位置:声明在公有中 (本身为函数)
声明:friend + 成员函数的声明
调用:先定义Y的对象y—使用y调用自己的成员函数—自己的成员函数中使用了友元机制
代码:
实现代码和2.4.2.3中的实现及其相似只是设置友元的时候变为friend void boy::disp(girl &);

主题2:pointer-like classes 智能指针

pointer-like classes 智能指针

template<class T>
class shared_ptr
{
public:T& operator*()const{return *px;}T* operator->()const{return px;}shared_ptr(T* p):px(p){};
private:T* px;long *pn;
};
struct FOO
{void method();
};
int main(int argc, char** argv)
{shared_ptr<FOO> sp(new FOO);FOO f(*sp);sp->method(); // == px->method(0)  ->会作用之后会继续出现->return 0;
}

pointer-like classes 迭代器

template <class T, class Refclass Ptr>
struct __list_iterator { //这是一个链表typedef __list_iterator<T, Ref, Ptr> self;typedef Ptr pointer;typedef Ref pointer;typedef __list_node<T>* link_type;link_type node;bool operator==(const self& x) const { return node == x.node; }bool operator==(const self& x) const { return node != x.node; }reference operator*() const { return (*node).data; }pointer operator-> const { return &(operator*())}self& operator++() { node = (link_type)((*node).next); return *this }self& operator++(int) { self tmp = *this; ++*this; return tmp; }self& operator--() { node = (link_type)((*node).prep); return *this }self& operator--(int) { self tmp = *this; --*this; return tmp; }
};

主题3: function-like classes 仿函数

template<class T>
struct identity
{const T& operator()(const T& x)const{return x;}
};

主题4:namespace

#include <iostream>
#include<list>namespace jj01
{
//开始设计template<typename T>using Lst=list<T,allocator<T>>;void test()
}
int main()
{jj01::test()
}

主题6: 模板

class template,类模板

Function template 函数模板

member template 成员模板

template <class T1,class T2>
struct pair  {typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() :first(T1()),second(T2())  { }pair(const T1& a,const T2& b) :first(a), second(b)  {  }template <class U1,class U2>  //这里,模板套模板,成员模板pair(const pair<U1,U2>& p): first(p.first),second(p.second)  {  }
};class Base1{};
class Derived1:public Base1{};pair<Derived1,Derived2> p;
pair<Base1,Base2> p2(p);
等价于pair<Base1,Base2> pw(pair<Derived1,Derived2>());  //用子类初始化父类

specialization 模板特化

template <class Key>
struct hash  {  };
--------------------上面的是泛化-------
template<>  //Key被锁定了
struct hash<char>  {size_t operator() (char x)  const  { return x;  }
}template<>  //Key被锁定了
strcut hash<int>  {size_t operator() (int x)  const  {return x;  }template<>  //Key被锁定了
struct hash<long>  {size_t operator() (long x)  const  {  return x;  }
};

parti specialization 模板偏特化

个数的偏

在这里插入图片描述
因为上面的模板有两个参数,但是目前我只需一个值绑定一个

范围的偏

在这里插入图片描述

template template parameter 模板模板参数

在这里插入图片描述
XCIS<string,list> mylist1; 第一个确定为string,但是第二个不确定传入模板;但是是错误的;虽然 Container变为 list但是一些容器的模板有一个以上的参数,我们一般只是定义了一个参数,上面不通过是由于语法问题参数不足导致
在这里插入图片描述
打岔:由于unique和weak的一些特性导致错误。
在这里插入图片描述
上面不是模板模板参数,由于list已经指定模板了

variadic templates 数量不定的模板参数

void print()
{cout<<"------"<<endl;}template<typename T,typename ... Types>
void print(const T& firstArg,const Types&...args)
{//  参数:一个 + 一包cout<<firstArg<<endl;cout<<sizeof...(args)<<ends;print(args...);
}
int main()
{print(7.5,"hello",42);/*
7.5
2 hello
1 42
0 ------这个模板参数可变的函数:参数可以分为一个+一包,这个函数是递归调用首先是:print(first=7.5,args=("hello",42)) 然后输出firstArg,然后size...(args)==2然后是:print(first="hello",args=(42)),打印出“hello”然后size...(args)==1最后是:print(first=42,args=),打印42,然后size...(args)===1调用无参数的print()*/return 0;
}

C++标准库

在这里插入图片描述

for(int i:{1,2,3,4})cout<<i;
//{1,2,3}是个容器

主题7:reference 引用

  1. object和其reference的大小相同,地址也相同(全都是假象)
  2. reference通常不用于声明变量,一般用于函数的参数类型和函数返回类型

主题8:对象模型

继承关系下的构造和析构

  1. 构造应该由内而外
  2. 析构应该由外二内

组合关系下的构造和析构

  1. 构造应该由内而外
  2. 析构应该由外二内

继承+组合 关系下的构造和析构

对象模型:vptr(虚指针)和vtbl(虚表)

  1. 只要一个类含有虚函数,那么该类一定含有虚指针。多一个虚函数就多一个虚指针
  2. 父类有虚函数子类一定有虚函数
    在这里插入图片描述
    函数:
  3. 静态绑定
  4. 动态绑定
    动态绑定的条件
  • 虚函数
  • 向上转型

this

主题9:const

  1. const只能放在成员函数后面

主题10:new delete

重载 operator new,operator new[],operator delete,operator delete[]

在这里插入图片描述

在这里插入图片描述
https://zhuanlan.zhihu.com/p/526244459

placement new

https://blog.csdn.net/qq_41453285/article/details/103547699

关于这里没有看明白(最后几节)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图像分类】CNN + Transformer 结合系列.4

介绍两篇利用Transformer做图像分类的论文&#xff1a;CoAtNet&#xff08;NeurIPS2021&#xff09;&#xff0c;ConvMixer&#xff08;ICLR2022&#xff09;。CoAtNet结合CNN和Transformer的优点进行改进&#xff0c;ConvMixer则patch的角度来说明划分patch有助于分类。 CoAtN…

GitHub不能正常打开以及CSS样式加载不成功的解决方案

大家好&#xff0c;今天分享GitHub不能正常打开以及CSS样式加载不成功的解决方案。当GitHub在没有“科学上网”的情况下&#xff0c;不能正常打开时&#xff0c;最直接的检测方法就是 ping 掉包情况。&#xff08;当然还有其它抓包的方法&#xff09;。通过 ping github.com可见…

专业商城财务一体化-线上商城+进销存管理软件,批发零售全行业免费更新

订货流程繁琐&#xff1f;订单处理效率低&#xff1f;小程序商城与进销存系统不打通&#xff1f;数据需要手动输入同步&#xff1f;财务与的结算对账需要大量手工处理&#xff1f;零售批发从业者&#xff0c;如何你也有以上烦恼&#xff0c;可以看看进销存小程序订货商城&#…

python几岁可以学零基础,python多大的孩子可以学

大家好&#xff0c;小编为大家解答多大的孩子可以学python的问题。很多人还不知道学python多大年龄可以学&#xff0c;现在让我们一起来看看吧&#xff01; python编程是现在很多孩子接触编程的好选择&#xff0c;它能够给孩子带来容易入门的效果。那么&#xff0c;python编程少…

基于星火和Gradio的聊天机器人

星火大模型官网&#xff1a;https://xinghuo.xfyun.cn/ 1 创建虚拟环境&#xff08;windows&#xff09; conda create -n Gradio python3.8 pip install gradio 中间遇到os报错&#xff0c;解决方案&#xff1a; pip install aiofiles23.2.1 2 代码 SparkDesk.py&#xff1a…

安卓:LitePal操作数据库

目录 一、LitePal介绍 常用方法&#xff1a; 1、插入数据&#xff1a; 2、更新数据&#xff1a; 3、删除数据&#xff1a; 4、查询数据&#xff1a; 二、LitePal的基本用法&#xff1a; 1、集成LitePal&#xff1a; 2、创建LitePal配置文件&#xff1a; 3、创建模型类…

[保研/考研机试] 括号匹配问题 C++实现

题目描述&#xff1a; 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母&#xff1b;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序&#xff0c;找到无法匹配的左括号和右括号&#xff0c;输出原来的字符串&am…

qemu 虚拟化

一、介绍QEMU Qemu是种非常古老的虚拟化技术&#xff0c;用于虚拟化系统组件并在其上运行多种CPU架构的程序或操作系统。 借助KVM&#xff0c;Qemu可以通过使用基于硬件的虚拟化来获得超快的计算速度。QEMU充当硬件供应商&#xff0c;KVM是CPU。KVM驻留在Linux内核中&#xff0…

数据挖掘具体步骤

数据挖掘具体步骤 1、理解业务与数据 2、准备数据 数据清洗&#xff1a; 缺失值处理&#xff1a; 异常值: 数据标准化&#xff1a; 特征选择&#xff1a; 数据采样处理&#xff1a; 3、数据建模 分类问题&#xff1a; 聚类问题&#xff1a; 回归问题 关联分析 集成学习 image B…

Windows安装Redis

自己电脑做个测试&#xff0c;需要用到Redis&#xff0c;把安装过程记录下&#xff0c;方便有需要的人 1、找到下载地址&#xff1a;Releases microsoftarchive/redis GitHub Windows的Redis需要到GitHub上下载&#xff1a; 2、下载完后设置密码&#xff0c;打开文件夹&…

Java | 异常处理

目录 一、异常概述 二、异常的抛出与捕捉 2.1 抛出异常 2.2 捕捉异常 2.2.1 try-catch语句块 2.2.2 finally语句块 三、Java常见的异常类 四、自定义异常 五、在方法中抛出异常 5.1 使用throws关键字抛出异常 5.2 使用throw关键字抛出异常 六、运行时异常 七、异…

idea创建SpringBoot项目

项目命名规范 项目名全部小写。包名全部小写。 一、点击 Create New Project 二、选择 Maven 点击Next 三、定义项目名称/组 四、定义项目名称 项目存储路径 五、完成创建 六、配置Maven 没配置之前 配置Maven&#xff1a; File > settings...> Build Execution Deplo…

[保研/考研机试] KY129 简单计算器 浙江大学复试上机题 C++实现

描述 读入一个只包含 , -, *, / 的非负整数计算表达式&#xff0c;计算该表达式的值。 输入描述&#xff1a; 测试输入包含若干测试用例&#xff0c;每个测试用例占一行&#xff0c;每行不超过200个字符&#xff0c;整数和运算符之间用一个空格分隔。没有非法表达式。当一行中…

构建IT项目价值管理体系︱陆金所控股有限公司项目管理专家朱磊

陆金所控股有限公司项目管理专家朱磊先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;陆控-构建IT项目价值管理体系。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; IT资源有限&#xff0c;…

模仿火星科技 基于cesium+水平面积测量+可编辑

​ 当您进入Cesium的编辑水平积测量世界&#xff0c;下面是一个详细的操作过程&#xff0c;帮助您顺利使用这些功能&#xff1a; 1. 创建提示窗&#xff1a; 启动Cesium应用&#xff0c;地图场景将打开&#xff0c;欢迎您进入编辑模式。 在屏幕的一角&#xff0c;一个友好的提…

山西电力市场日前价格预测【2023-08-10】

日前价格预测 预测明日&#xff08;2023-08-10&#xff09;山西电力市场全天平均日前电价为328.01元/MWh。其中&#xff0c;最高日前电价为366.62元/MWh&#xff0c;预计出现在20: 00。最低日前电价为283.28元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a; 实…

Linux 的基本使用

1、Linux 是什么 Linux 是一个操作系统. 和 Windows 是 "并列" 的关系 Linux 严格意义来说只是一个 "操作系统内核". 一个完整的操作系统 操作系统内核 配套的应用程序. CentOS 和 RedHat 的关系 RedHat一直都提供源代码的发行方式&#xff0c;Cent…

期刊和会议缩写查询网站

1.https://pubmed.ncbi.nlm.nih.gov/?termMedicalImageComputingandComputer-AssistedIntervention 2. http://www.letpub.com.cn/index.php?pagejournalapp&viewsearch 3. https://blog.csdn.net/weixin_44557349/article/details/120825927 https://blog.csdn.net/ret…

\vendor\github.com\godror\orahlp.go:531:19: undefined: VersionInfo

…\goAdmin\vendor\github.com\godror\orahlp.go:531:19: undefined: VersionInfo 解决办法 降了go版本(go1.18)&#xff0c;之前是go1.19 gorm版本不能用最新的&#xff0c;降至&#xff08;gorm.io/gorm v1.21.16&#xff09;就可以 修改交插编译参数 go env -w CGO_ENABLED1…

【Redis】Spring/SpringBoot 操作 Redis Java客户端

目录 操作 Redis Java客户端SpringBoot 操作Redis 步骤 操作 Redis Java客户端 1.Jedis 2.Lettuce(主流) <-Spring Data Redis SpringBoot 操作Redis 步骤 1.添加Redis 驱动依赖 2.设置Redis 连接信息 spring.redis.database0 spring.redis.port6379 spring.redis.host…