侯捷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

{

private:

  char *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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件测试的49种方法

1. α测试_Alpha测试 α测试&#xff0c;英文是Alpha testing。又称Alpha测试。 Alpha测试是由一个用户在开发环境下进行的测试&#xff0c;也可以是公司内部的用户在模拟实际操作环境下进行的受控测试&#xff0c;Alpha测试不能由该系统的程序员或测试员完成。 在系统开发接近…

一文看懂Apipost接口自动化使用方法

随着项目研发进程的不断推进&#xff0c;软件功能不断增多&#xff0c;对于软件测试的要求也越来越高。为了提高测试效率和减少测试成本&#xff0c;许多软件测试团队借助于自动化测试工具来优化测试流程。Apipost也提供了自动化测试工具&#xff0c;在本文中&#xff0c;我们将…

JVM深入 —— JVM的体系架构

前言 能否真正理解JVM的底层实现原理是进阶Java技术的必由之路&#xff0c;Java通过JVM虚拟机的设计使得Java的延拓性更好&#xff0c;平台无关性是其同时兼顾移动端和服务器端开发的重要特性。在本篇文章中&#xff0c;荔枝将会仔细梳理JVM的体系架构和理论知识&#xff0c;希…

中科驭数亮相DPU峰会,分享HADOS软件生态实践和大数据计算方案,再获评“匠芯技术奖”

又是一年相逢时&#xff0c;8月4日&#xff0c;第三届DPU峰会在北京开幕&#xff0c;本届峰会由中国通信学会指导&#xff0c;江苏省未来网络创新研究院主办&#xff0c;SDNLAB社区承办&#xff0c;以“智驱创新芯动未来”为主题&#xff0c;沿袭技术创新、生态协同的共创效应&…

开源数据库Mysql_DBA运维实战 (名词解释)

SQL&#xff08;Structured Query Language 即结构化查询语言&#xff09; SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统&#xff0c;SQL语言由IBM开发。 SQL语言分类&#xff1a; DDL语句 数据库定义语言&#xff1a;数据库、表、视图、索引、存储过程…

单片机、嵌入式的大神都平时浏览什么网站?

我平时也喜欢收藏些有关嵌入式的学习网站&#xff0c;压箱底的记录翻出来总结下 1、综合网站 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili//B站是一个有很多好资料的网站 https://github.com/nhivp/Awesome-Embedded //github开源项目网站&#xff0c;这个是我找到嵌入式综合相关的…

24届华东理工大学近5年自动化考研院校分析

今天给大家带来的是华东理工大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、华东理工大学 学校简介 华东理工大学原名华东化工学院&#xff0c;1956年被定为全国首批招收研究生的学校之一&#xff0c;1960年起被中共中央确定为教育部直属的全国重点大学&#…

yolo txt 转 labelme json 格式

talk is cheap show me the code! def convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt.jpg):# txt 转labelme json# 将yolo的txt转labelme jsontxts glob.glob(os.path.join(txt_path, "*.txt"))for txt in txts:labelme_json {versio…

Centos7离线安装MySQL8

1、下载MySQL https://downloads.mysql.com/archives/community/ 2、下载完毕后&#xff0c;上传到Centos&#xff0c;解压 tar -xf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 3、逐条执行安装命令 rpm -ivh mysql-community-common-8.0.33-1.el7.x86_64.rpm rpm -ivh …

容器——2.Collection 子接口之 List

文章目录 2.1. Arraylist 和 Vector 的区别?2.2. Arraylist 与 LinkedList 区别?2.2.1. 补充内容:双向链表和双向循环链表2.2.2. 补充内容:RandomAccess 接口 2.3 ArrayList 的扩容机制 2.1. Arraylist 和 Vector 的区别? ArrayList 是 List 的主要实现类&#xff0c;底层使…

利用Ettercap进行DNS欺骗攻击

一、域名系统&#xff08;DNS&#xff09; 域名系统DNS是Internet上使用的命名系统&#xff0c;用于将系统名称转换为人们易于使用的IP地址。域名系统是基于互联网的前身ARPANET开发的&#xff0c;在ARPANET时代&#xff0c;主机名和对应的IP地址是通过HOST.TXT文件集中管理的…

ffplay简介

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 ffplay播放器的意义 ffplay.c是FFmpeg源码⾃带的播放器&#xff0c;调⽤FFmpeg和SDL API实现⼀个⾮常有⽤的播放器。 ffplay实现了播…

沁恒ch32V208处理器开发(一)开发环境

目录 简介&#xff1a;开发环境开发界面自定义风格 烧录工具支持范围烧录界面 简介&#xff1a; CH32V2x 系列是南京沁恒基于 32 位 RISC-V 指令集及架构设计的工业级通用微控制器。采用青稞 V4 内核&#xff0c;支持硬件中断堆栈&#xff0c;提升中断响应效率&#xff1b;CH3…

计算机网络(5) --- http协议

计算机网络&#xff08;4&#xff09; --- 协议定制_哈里沃克的博客-CSDN博客协议定制https://blog.csdn.net/m0_63488627/article/details/132070683?spm1001.2014.3001.5501 目录 1.http协议介绍 1.协议的延申 2.http协议介绍 3.URL 4.urlencode和urldecode 2.HTTP协…

04-2_Qt 5.9 C++开发指南_SpinBox使用

文章目录 1. SpinBox简介2. SpinBox使用2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. SpinBox简介 QSpinBox 用于整数的显示和输入&#xff0c;一般显示十进制数&#xff0c;也可以显示二进制、十六进制的数&#xff0c;而且可以在显示框中增加前缀或后缀。 QDoubleSpinBox…

如何测试Linux磁盘的读写速度

在Linux系统中也有很多命令可以测试硬盘的读写速度指标。以下是几个常用命令&#xff08;注意&#xff1a;在执行测试命令之前&#xff0c;请务必备份数据以避免数据丢失&#xff01; 1、dd 命令 首先挂载磁盘 mount /dev/sdb /testdd 命令可用于进行硬盘读写速度测试。 例…

低功耗LoRaWAN国产低功耗LoRa+RF射频前端芯片XD6500S

目录 典型应用XD6500S简介芯片特性 LoRa系列选型参考 LoRa是为低数据速率、远距离距离和超低功耗而优化的扩频协议&#xff0c;用于LPWAN应用程序的通信。 典型应用 一、智慧农业   智慧农业大田解决方案利用传感设备、自动化控制设备、气象站实时监测采集田间土壤墒情、气象…

Power BI中实现购物篮分析详解

一、购物篮分析简介 相信&#xff0c;很多人都听过沃尔玛购物篮分析的故事---“啤酒和尿布湿“&#xff0c;即分析购买尿布湿的顾客最喜欢购买的商品是什么&#xff1f;&#xff08;啤酒&#xff09;。在零售终端经营中&#xff0c;通过购物篮分析&#xff0c;分析不同商品之间…

CD4029计数器实测仿真及BCD转七段码

前面的博文中&#xff0c;我们介绍过CD40110(这是一个常见的直接接7段数码管的计数器&#xff0c;我们这里介绍一款新的计数器CD4029&#xff0c;这也是很常见的计数器&#xff0c;不同的是后者可以输出BCD编码。 文章目录 一、总体效果二、CD4029的管脚和功能介绍1、芯片功能简…

Spring 知识点

Spring 1.1 Spring 简介 1.1.1 Spring 概念 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题Spring最根本的使命是解决企业级应用开发的复杂性&#xff0c;即简化Java开发。使现有的技术更加容易使…