C++ 面向对象

news2024/9/25 17:16:57

C++ 面向对象,内存管理(未完。。。)

对象内存模型

类型转换 dynamic_cast type_info

多态

  • 虚函数 override final
  • 虚表结构 运行时类型信息(RTII)
  • 基类析构函数必须为虚函数,否则会有内存泄漏的危险
  • 继承有两层含义
    • 实现继承:复用父类定义的数据成员和函数成员
    • 接口继承:通过父类定义虚函数来约定函数的行为
  • 虚继承时,内存中会多一个指针,指向虚继承的基类,可避免菱形继承中重复继承的情况

在这里插入图片描述

Pimp设计习语

  • Pointer to Implementation,将类数据成员声明为指针,指向某具体实现类或抽象类(前置声明)
  • 编译依赖:消除头文件对实现类的以依赖(只需要声明,无需定义)
  • 延迟分发:如果使用指针指向抽象类,由于虚函数的多态,将函数的调用延迟到运行时,将具有更好的弹性
RAII(资源获取即初始化)
  • RAII(Resource Acquisition Is Initialization)是c++内存和资源管理最重要的管理机制之一
  • RAII通过三个环节来保证内存或资源得到确定行的释放
    • 构造器中获取内存或资源
    • 析构器中释放内存或资源
    • 栈对象在作用域结束即确定行调用析构器回收内存(编译器自动管理)
  • 异常免疫,出现异常也能够确定析构
  • 可以同时管理内存对象与非内存对象(文件句柄,锁,网络IO…)
  • 不仅管理栈对象、同时管理堆对象
  • RAII与移动语义、智能指针结合,可达成资源管理正确性和性能的双重保证
Move(移动语义)
  • 移动发挥最大价值的场景
    • 对象内部有分离内存(通常是指指针指向的堆内存)
    • 对象拷贝为深拷贝
  • 移动仅仅复制对象内本身的数据,不复制分离内存;拷贝即赋值对象本身数据,也复制分离内存
  • 移动永远不比拷贝慢,通常更快,移动是拷贝的优化
  • 移动构造函数/移动赋值操作符
  • 对象移动之后不再使用(即右值)

字符串字面量(const字符数组)是左值 “qwert”; 字符串字面量对象是右值 (“qwer”s)

  • void func(vector&& v)
  • 类型为右值引用的函数形参,其实是个左值
    • 对于函数调用者来说,v是一个右值引用参数
    • 对于函数内不来说,v是一个左值
  • 移动一个左值是不安全的

有移动构造,编译器会调用移动构造,没有移动构造函数,调用普通构造函数、

返回值优化 > 移动 > 拷贝(返回值优化必须是对象初始化时才会发生,函数参数不会做返回值优化)

构造函数可以抛异常,析构函数不可以抛异常

含有智能指针的类对象,编译器自动生成的拷贝构造函数和赋值操作符是不正确的,要自己实现

sdynamic_cast<sub*>(b2.release())

智能指针最佳使用场景
  • 智能指针仅用于内存管理,不要用于管理非内存资源,非内存资源使用RAII类封装
  • 优先使用unique_ptr而不是shared_ptr,除非需要共享使用权
  • 使用make_unique()创建unique_ptr
  • 使用make_shared()创建shared_ptr
  • 使用weak_ptr 防止shared_ptr 的循环引用
模板编程
  • c++模板是一种编译时机制,在编译时生成具体代码,使用实参将模板定义时类化为具体的类型或参数;c++支持两种模板参数:类模板、函数模板

  • 模板实例化时,编译器会对实参类型进行检查,确保实参类型符合模板参数的操作要求;C++模板参数支持两种:

    • 类型参数,可隐式约束、也可以显示约束
    • 值参数、编译时常量、或constexpr函数,不同值参数是不同类型
  • 数据成员:只要类型被使用,编译器胡根据其数成员、生成对应类型结构

  • 函数成员–选择性实例化

    • 非虚函数,如果实际调用到,则会生成代码;如果没有调用到,则不生成
    • 虚函数,无论是否调用,总会生成代码,因为在运行是,有可能调用到;
  • 隐藏编译错误:如果某些模板方法没有被调用,即使含又编译错误,也会被忽略

  • 强制实例化模板

    • 使用template class name; 来强制要求编译所有模板类函数成员,可以排除所有编译错误
  • 模板类型推导

    • 引用性被忽略:引用类型的实参被当作非引用类型使用
    • 转发引用:左值参数按左值,右值参数按右值
    • 安置传递:实参中的const/volatile修饰会被去掉,都为拷贝
类的萃取(Trait)
  • 通过附加属性,基于类型特征来提供正交设计的灵活性
  • 聚合了各种相关的类型和变量,一般不包含成员函数
  • 可以是固定traits(不使用模板参数化),也可以是模板,可以构成Traits Template
  • Trait参数通常依赖其他模板的参数
  • 作为模板参数,通常有默认值
  • traits与policy的区别:traits基于类型特征,policy基于行为特征
c++20概念
template<typename T>
concept IsPointer = std::is_pointer_v<T>;

template<typename T>
concept CanCompute=requires(T x, T y) {
    x + y; // 支持+
    x - y; // 支持 -
    x * y;   //支持 * 
    x / y;
};
template<CanCompute T>
T compute(T a,T b)
{
    return (a+b)*(a-b);
}  
int main()
{
    int x=200, y=100;
    cout << compute(x, y) << endl; 
    string s1="hello ", s2="cpp";
    cout << compute(s1, s2) << endl;//错误的调用,不支持CanCompute概念的约束
}
  • c++概念是一种显示的类型接口,再编译时执行类型约束检查,是泛型编程的灵魂
  • 概念可以帮助根号的理解泛型组件之间的合约
  • 有概念约束的版本,可以van与重载百辨析,相当于通用版本的一个特化
  • 概念比traits、编译时表达式都更强大的抽象
  • 概念是一种约束,不是代码,没有类型、存储,生命周期以及地址等
  • 概念本质是一组对类型参数T的编译时表达式求值 true或false
requires表达式约束
  • requires表达式可以指定多个类型约束,多个约束是没有顺序关系,可以是一下组合
    • 编译时bool值表达式:类型判断式,编译时变量或函数
    • requires表达式:类型定义,有效表达式,表达式残生的类型需求
    • concept
  • requires表达式执行是编译时检查,对运行时代码没有任何影响、没有性损失
  • 多个约束之间何以使用 && 或 || 实现逻辑组合

模板元编程

  • 使用模板在编译时操作类型和函数的编程,成为模板元编程

    • 提高性能:将部分计算冲运行时一道编译时
    • 类型安全:计算一个数据结构或者算法的准确类型
  • 泛型编程和模板元编程

    • 泛型编程是通过玉树模板参数的定义,进行通用的类型、算法设计;更关注接口合同(concept)
    • 模板元编程时通过编译时选择、或者某中形式的迭代,将类型当作值,进行编译时计算
  • constexpr 具有常量属性,同时具有编译时确定性;const 仅仅具有常量属性,但是并不确保编译期确定性

  • constexpr可以应用于一切休要编译时常量的地方(数组大小,模板值参数,枚举数值)

  • constexpr也可以用于函数和成员函数

int a = 100;
const int a1 = 100;	//编译时常量
int array1[a1];		//正确
const int a2 = a;	//运行时常量
int array2[a2];		//c++中错误(行为未定义),c中正确(栈变长数组)
constexpr int a3 = 100;//编译时常量
constexper函数
  • 支持全局函数,类成员函数,模板函数,只要满足编译时常量的计算要求
  • 如果结果要求未编译时常量:
    • 传参为编译时常量,函数可以正常得到编译时常量值
    • 传参为运行时变量,函数编译报错
  • 如果结果要求为运行时变量:
    • 参数传值可以时运行时变量,也可以为编译时值
//可变参模板
template<typename T, typename... Types>
void print (T const& firstArg, Types const&... args)
{
    cout << firstArg << endl;
    if constexpr(sizeof...(args) > 0) {
        print(args...); 
    }
}
//模板元编程案例一
template<int n> constexpr int fib()
{
    return fib<n-1>() + fib<n-2>();
}
template<> constexpr int fib<1>()
{
    return 1;
}
template<> constexpr int fib<2>()
{
    return 1;
}
//模板元编程案例二
template<int n> struct Fib
{
    static constexpr int value=Fib<n-1>::value+ Fib<n-2>::value;
};

template<> struct Fib<1>
{
    static constexpr int value=1;
};

template<> struct Fib<2>
{
    static constexpr int value=1;
};

int main()
{
    //1,1,2,3,5,8,13,21,34,55
    constexpr int f6= Fib<6>::value;//编译时常量
    constexpr int f10= Fib<10>::value;//编译时常量
    cout<<f6<<endl;
    cout<<f10<<endl;
}

static constexpr int value=1;
};

int main()
{
//1,1,2,3,5,8,13,21,34,55
constexpr int f6= Fib<6>::value;//编译时常量
constexpr int f10= Fib<10>::value;//编译时常量
cout<<f6<<endl;
cout<<f10<<endl;
}


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

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

相关文章

GitHub 推出对所有公共存储库的免费秘密扫描

GitHub 正在推出对其代码托管平台上所有公共存储库的免费扫描公开秘密&#xff08;例如凭据和授权令牌&#xff09;的支持。 秘密扫描是一种安全选项&#xff0c;组织可以启用它以进行额外的存储库扫描&#xff0c;以检测已知类型的秘密的意外暴露。 它通过匹配合作伙伴和服务…

【Java编程系列】Mybatis的Interceptor注入yml自定义变量,多种实现方式

1、前言 当前有一个任务&#xff0c;需要将mybatis的sql进行拦截过滤处理&#xff0c;而拦截处理时&#xff0c;需要有一些白名单放行的配置方法名路径。所以&#xff0c;这里使用到了yml的配置文件来配置变量路径&#xff0c;而后引入拦截器做动态放行。 2、注入自定义变量方式…

5点起床,一直干到11点的外卖小哥转行程序员,入职起薪12K

“我是要成为卷王的男人”是95后的小魏的座右铭&#xff0c;曾经的他5点起床&#xff0c;10分钟洗漱完毕就开始了一天的工作—送外卖。是的&#xff0c;曾经的他是万千外卖小哥的其中一员。 19年毕业的小魏学的是土木工程&#xff0c;曾经他也在工地待过&#xff0c;风尘仆仆却…

教程!!!!!

使用门槛&#xff1a;需要自行准备能开全局代理的科学工具 好评赠送免费科学工具&#xff0c;也可以自己准备科学工具。 下单以后&#xff0c;我们会发送一串账号密码给您。如图&#xff1a; 其中卡号就是chatgpt的账号&#xff0c;密码就是chatgpt密码。 第一步&#xff1…

星火计划学习笔记——第八讲Apollo控制模块解析与实践1

文章目录1. 控制理论简介1.1 控制的作用1.2 自动驾驶控制的目标1.3自动驾驶控制器的设计2. 汽车运动学与动力学2.1 常用的自动驾驶控制算法2.2 车辆运动学模型 Kinematics2.3 车辆动力学模型 Dynamics3. Apollo控制模块3.1 Apollo控制模块3.2 规划与控制相配合3.3 Apollo控制模…

零基础学习编程,选择什么编程语言比较合适?

随着互联网的兴起&#xff0c;越来越多的人想要学习编程&#xff0c;却不知道该从哪开始学&#xff0c;小编就通过以下几点给大家分析一下&#xff0c;零基础入门学习编程&#xff0c;该如何选择编程语言。 1、哪一门语言容易入门&#xff01; 所有语言的知识体系分为三大块&…

SAP ABAP 物料主数据的视图维护状态

SAP ABAP 物料主数据的视图维护状态 引言&#xff1a; 物料主数据的视图维护状态会经常使用&#xff0c;是物料主数据批量创建/修改的逻辑路由。 关键字&#xff1a;SAP ABAP VPSTA PSTAT T132T 文章目录SAP ABAP 物料主数据的视图维护状态1. 技术说明2. 维护状态3. 维护记录…

Linux——实用指令

帮助指令 man 获得帮助信息 基本语法 man [命令或配置文件] 注意&#xff1a;命令可以组合使用&#xff0c;比如ls -al&#xff0c;ls -la help 获得shell内置命令的帮助信息 基本语法 help命令 时间日期类 date指令 显示当前日期 基本语法 date&#xff08;显示…

【细胞分割】原子力显微镜图像分析【含GUI Matlab源码 1371期】

⛄一、AFM简介 理论知识参考文献&#xff1a;原子力显微镜&#xff08;AFM&#xff09;图像的计算机辅助分析 ⛄二、部分源代码 function varargout AFManalysis(varargin) % AFMANALYSIS M-file for AFManalysis.fig % AFMANALYSIS, by itself, creates a new AFMANALYSIS…

【图像处理】高效斑点特征提取技术研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

10年经验Python老司机分享:转行如何自学Python并且找到工作?

目前信息化产业发展势头很好&#xff0c;互联网就成为了很多普通人想要涉及的行业&#xff0c;因为相比于传统行业&#xff0c;互联网行业涨薪幅度大&#xff0c;机会也多&#xff0c;所以就会大批的人想要转行来学习Python开发。 零基础学习Python必须明确的几点&#xff1a; …

5个千兆网口,将有什么样高速网络传输体验?——米尔MYD-J1028X开发板实测分享

本篇测评由电子工程世界的优秀测评者“HonestQiao ”提供。 此次的板卡测试&#xff0c;是米尔MYD-J1028X开发板的高速网络数据传输测试体验。 01 本次测试的主角 米尔MYD-J1028X开发板提供了5个超级给力的最高支持千兆网络接口&#xff0c;具体如下&#xff1a; 通过查看官…

基于AD936X+Intel FPGA的射频方案

基于ADI AD936X和Intel Cyclone V FPGA的射频方案&#xff0c;适合于无线通信基础设施、防务电子系统、RF测试设备和仪器以及通用软件定义无线电平台等应用。 关于ADI AD936X系列射频收发器 AD936X系列的工作频率范围覆盖从70 MHz到6 GHz。它是一系列完整的无线电设计&#x…

底层网络知识详解:最重要的传输层-第11讲-TCP协议(上):因性恶而复杂,先恶后善反轻松

上一节,我们讲的UDP,基本上包括了传输层所必须的端口字段。它就像我们小时候一样简单,相信“网之初,性本善,不丢包,不乱序”。 后来呢,我们都慢慢长大,了解了社会的残酷,变得复杂而成熟,就像TCP协议一样。它之所以这么复杂,那是因为它秉承的是“性恶论”。它天然认…

Dubbo 4 Dubbo 高级特性 4.2 Dubbo 常用高级配置 4.2.7 集群容错 4.2.8 服务降级

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 4 Dubbo 高级特性 文章目录Dubbo4 Dubbo 高级特性4.2 Dubbo 常用高级配置4.2.7 集群容错4.2.8 服务降级4.2 Dubbo 常用高级配置 4.2.7 集群容错 【一个场景】 现在 服务 提供者 部署成 了一个集群&a…

痞子衡嵌入式:我被邀请做科锐国际旗下数科同道主办的技术沙龙嘉宾

「数科同道」是「科锐国际」旗下的面向技术开发者的专属垂直招聘平台。《数科同道技术沙龙》是由数科同道主办的活动&#xff0c;每期活动邀请行业内及其他知名公司的技术专家分享来自一线的实践经验。自2022年12月起&#xff0c;数科同道将在苏州&#xff0c;聚焦嵌入式行业及…

【Cadence Virtuoso】IC617 入门操作 (MOS特性分析)

Cadence Virtuoso IC617 入门操作篇前言一、软件操作&#xff08;1&#xff09;创建自己的Library&#xff08;2&#xff09;创建Library下的 Cell二、电路搭建&#xff08;1&#xff09;调出器件三、电路仿真&#xff08;1&#xff09;打开仿真工具“ADE L”(2) 对参数进行赋值…

【MATLAB教程案例63】学习如何建立自己的深度学习训练样本库,包括分类识别数据库和目标检测数据库

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 1.软件版本 2.建立自己的深度学习训练样本库1——分类识别数据库

纯精华、二十八道BATJ大厂Java岗之“多线程与并发“面试题分享

年底了&#xff0c;又到了跳槽季啦&#xff0c;该刷题走起了。这里总结了一些被问到可能会懵逼的面试真题&#xff0c;有需要的可以看下&#xff5e; 一、进程与线程 进程是资源分配的最小单位&#xff0c;线程是cpu调度的最小单位。线程也被称为轻量级进程。 所有与进程相关…

内存读写指令 —— LDR / STR

CPU在处理C语言的 a 操作时&#xff0c;变量a因为是放在在内存里的&#xff0c;需要先把a从内存中读取到寄存器中&#xff0c;运算完毕后再保存到内存中。 因此&#xff0c;这个过程中肯定需要用到内存的读写指令。 目录 1、基本内存读写指令&#xff08;4个字节读写&#xf…