类和类之间关系
类外: 静态变量,是在编译阶段就分配好空间,对象还没创建的时候就有了空间
类:类-对象-对象是类的一个实例
类头(class head)和类体(class body)。 将数据和行为封装在单个单元中--封装
成员变量 成员函数 成员变量称为属性(property);成员函数称为方法(method)
静态成员变量 在内存中只有一个副本,为所有类的实例共享。
静态成员变量必须在类中声明,类外定义。声明时使用关键字static ,定义的时候不用加static
静态成员函数: 属于类不属于对象,静态函数能操作静态数据,不能操作非静态数据
共享(static),又要实现不能修改(const),static前面加上const,
成员函数的--参数和局部变量
成员函数--其他类的静态方法
成员变量--引用其他类的全局变量 其他类的属性 其他类的实例-其他类的对象
空类:
在空类情况下编译器会自动生成以下6个默认成员函数。
亲疏远近
类之间的关系强弱顺序是这样的:继承(泛化) > 组合 > 聚合 > 关联 > 依赖。
关系:
继承--泛化关系 is a Generalization
实现--Realization
虚函数 中使用的关键词是 virtual :虚函数是在基类中声明为虚函数的函数,可以有默认实现,在基类中有默认的实现,但也可以被子类重写
纯虚函数 定义纯虚函数的语法是在函数声明后面加上 “= 0” 基类中声明但是没有定义的虚函数,它的定义留给了派生类
如果类中存在纯虚函数,则这个类被称为抽象类,抽象类不能被实例化
C++通过 虚函数(Virtual Function) 实现运行时多态性
函数的重写: 派生类中重新定义基类--方法具有相同的函数名-相同的参数列表--相同的返回值类型
重写是在派生类中重新定义虚函数,函数签名必须与基类中的虚函数一致
组合关系 contains a 组合(Composition) 同生共死 的关系
聚合关系 has a
关联(Assocition)
依赖关系 use a
C++ 重载(Overloading)
在同一个作用域内声明多个同名的函数或运算符
重载函数
const修饰类成员函数,实际限制的是*this,表明该成员函数不能对类的任何成员进行修改
const对象只能调用不会修改数据成员的const方法
运算符重载 :返回值类型 operator操作符(参数列表)
重载运算符--新的运算符行为 --不能改变运算符的优先级和结合性 运算对象数量和格式不能改变 不能发明新的运算符
有两个方法,第一种就是在类内部写成员函数实现,
第二种全局函数实现,两个方法都有一个功能的函数名称
以加号为例:
operator+(), 这个函数名称是固定
全局函数重载+号运算符 Person p3 = operator+(p1,p2);我们习惯简写成 p3 = p1 + p2 的代码形式
成员函数重载+号运算符 Person p3 = p1.operator+(p2);我们习惯简写成 p3 = p1 + p2 的代码形式
说明: 运算符是不能重载 只能重载成全局函数的运算符 只能重载成成员函数的运算符
左值与右值(Lvalue/Rvalue)
同类对象之间可以通过赋值运算符“=”互相赋值 如果没有经过重载相当于值的拷贝, 称为“浅拷贝”。
左值可以取地址、位于等号左边;而右值没法取地址,位于等号右边。
左值引用和右值引用
传统的C++引用,即是左值引用
右值引用:
右值引用使用 && 符号来声明,表示对右值的引用
右值不具名,只能通过引用的方式找到
std::move(),它可以将一个左值强制转换为右值引用
移动语义
对象的所有权转移 左值对象转换为右值对象,使得后续的操作可以使用移动语义而非拷贝语义
运算符重载原型 函数原型:返回值类型 operator操作符(参数列表)
传输值(拷贝和移动 copy and move ) 使用了相同的符号--将左值和右值的处理分离开来,左值-拷贝赋值和拷贝构造 右值-移动赋值和移动构造
拷贝操作
X(const X&)
X& operator=(const X&)
移动操作
X(X &&)
X& operator=(X&&)
构造和析构
X() ~X()
取地址及const取地址操作符
X* operator&()
const X* operator&() const
C++运算符
* 指针运算符
& 取地址符 返回操作数的内存地址
* 是一元运算符,返回操作数所指定地址的变量的值
& 引用运算符 数据类型与变量名称的中间。
形参实际是重新在栈申请了变量空间,增大了内存开销,而引用可以理解为替换符,并没有申请多余的变量空间。
std::forwad() 相应实参是左值,则被转发为左值;同理如果相应实参为右值,则被转换为右值。
默认引入
C编译器
C 语言标准-- main函数:程序的默认入口点 在大多数情况下,main函数是C程序的入口点
非标准操作-- 借助编译器特性和链接器选项,我们可以指定其他函数作为程序的入口
还可以通过链接脚本(linker script)来控制程序的入口点
C++ 编译器会自动生成以下6个默认成员函数。
哪些: 默认的 构造函数、析构函数、
默认重载取址运算符函数 默认重载取址运算符函数const函数
拷贝构造函数、以及默认重载赋值运算符函数
默认移动构造函数(c++11) 默认重载移动赋值操作符函数(c++11)
C++默认拷贝构造函数执行的是浅拷贝操作
= ,但移动构造函数是构造了一个新对象,移动赋值运算符是对已存在的对象赋值
拷贝,然后再销毁临时对象的资源
即将被销毁的对象移动到接收对象,而不是复制
std::move()用于将左值转换为右值引用,允许资源的有效转移
std::move()是一个标准模板函数,它可以将一个左值转换为一个右值引用,从而触发移动语义。
std::move()并不真正移动任何东西,只是改变了对象的类型
什么时候: 默认构造函数“被需要”的时候编译器才会帮我们合成
充要条件,必要不充分条件
如果没有经过重载,“=” 的作用就是将赋值号右侧对象的值
重载赋值操作会将对象的成员变量逐个复制到另一个对象中--深拷贝”
内存拷贝是指将一段内存中的数据复制到另一段内存中。通常使用内存拷贝函数如memcpy()或std::copy()来实现
std::forward()
默认引入-无需显式地导入
Rust -默认引入std库--CORE库、ALLOC库 STD库
Cangjie 默认引入 core std.core 包不需要显式导入,默认导入 core 包是标准库的核心包,提供了适用仓颉语言编程最基本的一些 API 能力
Java 默认引入的 java.lang
Python 默认引入 __built_in__ __main__
继承-封装-多态
面向对象设计(Object-Oriented Design)--源代码依赖关系-以对象为手段来对源代码中的依赖关系进行控制的能力
封装 特性其实并不是面向对象编程所独有的。其实,c 语言也支持完整的封装
C++通过在编程语言层面引入 public、private、protected 这些关键词,部分维护了封装性
继承 的主要作用是让我们可以在某个作用域内对外部定义的某一组变量与函数进行覆盖。这事实上也是 c 程序员早在面向对象编程语言发明之前就一直在做的事
C++的继承-便利和易用
多态: 例如:UNIX 操作系统强制要求每个 IO 设备都要提供 open、close、read、write 和 seek 这 5 个标准函数,多态其实不过就是函数指针的一种应用
C++中,类中的每个虚函数(virtual function),让多态变得更安全和便于使用
面向对象编程 其实是对程序间接控制权的转移进行了约束。插件式架构就 allows the plugin architecture to be used anywhere, for anything.
类定义:将数据和行为封装在单个单元中--封装
定义和使用其他类
类(class)中的公共函数和私有成员变量
类--继承
C++11标准引入final说明符它告诉编译器该虚函数不能被派生类重写
多态:C++的多态性体现在两个方面:运行时多态和编译时多态
通过继承、虚函数和运算符重载等方式实现
重写(override)
而重载是在同一作用域内定义多个函数,函数名和返回值类型一致但 函数的签名不一致。
重载(overload
C++通过 函数重载(Function Overloading) 和 模板(Template) 实现编译时多态性
重载 指的是在同一作用域内函数的函数名不变,可以有变化的是函数的参数列表,
具体指的是参数列中的参数数量、参数类型和参数的顺序可以变换。
模板是一种通用的编程机制,可以根据所传递的类型参数来生成特定的函数或类。函数模板和类模板 template
C++通过 虚函数(Virtual Function) 实现运行时多态性--重写(override)的意思更接近覆盖
override说明符,这个说明符必须放到虚函数的尾部,它明确告诉编译器这个虚函数需要覆盖基类的虚函数
继承--泛化关系 is a Generalization
继承与派生是同一个过程的两种描述方式。
从子类角度,由父类继承;从父类角度,子类是派生出的
关联关系:聚合和组合的最关键区别是两个对象的生命周期是否一致,而不是出现的形式
组合关系 contains a 组合(Composition) 同生共死 的关系
被组合的对象 在 组合对象创建的 同时或者创建之后 创建,在组合对象销毁之前销毁
聚合关系 has a
关联(Assocition)
单向关联、双向关联、自关联将一个类的对象 作为 另一个类的成员变量。
依赖关系 use a 依赖(Dependency)关系是一种 使用关系
大多数情况下依赖关系体现在某个类的方法 使用 另一个类的对象 作为参数。
(一)依赖:
1. 概念:是一种使用关系,耦合度最弱。
类A使用类B的一部分属性和方法,不会主动改变类B的内容,但是类B的变化会影响到A。
具有偶然性、临时性。
2. 体现:
类B 作为 类A的 成员函数参数。
类B 作为 类A的 成员函数的局部变量
类A的成员函数调用的 类B的静态方法
3. 代码:
被关联类B 以类的属性形式出来在关联类A中。
关联类A 引用了一个类型为被关联类B的全局变量。
设计模式
底层设计信息和顶层架构设计共同组成了整个房屋的架构文档,满足构建和维护该系统的需求
The only way to go fast, is to go well.
OCP,Open For Extension Closed For Modification Principle,简称开闭原则。开闭原则是指软件实体是可以扩展的,但是不可修改
模块和函数是对扩展(提供方)开放的,对修改(使用方)关闭的
SRP,Single Responsibility Principle,单一职责原则
DIP,Dependence Inversion Principle,依赖倒置原则。抽象不应该依赖于细节,细节应该依赖于抽象
ISP,Interface Segegation Principle,接口隔离原则。一个接口对外只提供一种功能,不同功能应该通过不同的接口提供,而不是把多种功能都封装到一个接口中
LSP,Liskov Substitution Principle,里氏替换原则。任何地方出现的抽象类,都可以使用该抽象类的实现类来代替,
CARP,Composite/Aggregate Reuse Principle,优先使用对象组合而不是继承原则
LOD,Law of Demeter,迪米特法则,也叫做最少知道原则(The Least Knowledge Principle
设计模式---经验
第一类是创建型模式 ,该模式通常和对象的创建有关,涉及到对象实例化的方式
单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式五种;
第二类是结构型模式,结构型模式描述的是如何组合类和对象来获得更大的结构
代理模式、装饰者模式、适配器模式、桥接模式、组合模式、外观模式、享元模式共7种模式。
第三种是行为型模式,用来描述对类或对象怎样交互和怎样分配职责
模板模式、命令模式、责任链模式、策略模式、中介者模式、
观察者模式、备忘录模式、访问者模式、状态模式、解释器模式、迭代器模式11种模式。
创建型模式主要是将系统所需要的用到的具体类封装起来,在内部实现这些具体类的创建和结合,并对外隐藏这个过程细节
Prototype Pattern,原型模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例
深拷贝浅拷贝问题
单例模式: 一个类只能创建一个实例对象
(禁止类的外部访问构造函数 解决办法就是把构造函数设置为私有属性,在类的内部完成实例化对象的创建
提供一个全局访问点来获取类内部创建好的对象)
Simple Factory Pattern,简单工厂模式
通过一个专门的类(工厂)来负责创建其他类的实例(具体产品),这些类都有一个共同的抽象类作为基类(抽象产品)。
factory pattern,工厂模式同样属于类的创建型模式,也成为多态工厂模式
工厂模式多出了一个抽象工厂角色作为接口,实际的生产工作在具体工厂类中实现
Abstract Factory Pattern,抽象工厂模式
一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构
Bulider Pattern,建造者模式,也叫做生成器模式,是一种对象创建型模式
强调的是建造过程,要关注每一个部件的建造方式,以及各个部件的建造逻辑,最终组合出需要的对象
结构型模式
Proxy Pattern,代理模式 客户端只有通过Proxy来实现与被代理类的交互,并且在交互过程中 ,代理可以增加其它操作
Decorator Pattern,装饰模式,也叫做包装模式,是结构型模式的一种:装饰模式的具体实现就是把一些功能封装在一个个单独的子类中
Adapter Pattern 适配器模式 适配器模式可以将一个类的接口转换成客户希望的另一种形式的接口
Composite Pattern,组合模式
Bridge Pattern,桥接模式
Facade Pattern,外观模式 Flyweight Pattern,享元模式 享元模式的目的就是使用共享技术来实现大量细粒度对象的复用。
行为型模式
Template Pattern,模板方法模式 通过子类继承对抽象算法进行不同的实现来达到改变算法行为的目的
Command Pattern,命令模式,是一种行为型设计模式
Chain of Responsibility Pattern,CoR责任链模式,
Strategy Pattern,策略模式
Mediator Pattern,中介者模式
Observer Pattern,观察者模式:
一种一对多的模式,多个观察者对象同时监听一个主题对象,一旦主题对象发生变化,能够自动通知所有的观察者对象。
它提供了一种关联对象之间的同步机制,他们之间通过通信来保持状态同步。
Visitor Pattern,访问者模式
把数据结构和作用于数据结构上的操作进行了分离,在不修改已有类的前提下可以增加新的操作,而新增新的操作就相当于新增一个访问者。
Memento Pattern,备忘录模式
State Pattern,状态模式:通过改变对象的内部状态来达到改变对象行为的目的
interpreter Pattern,解释器模式
Iterator Pattern,迭代器模式
架构
--应对复杂系统的方式
还是宏观层面的架构,无论是三种编程范式还是微服务架构,它们都在解决一个问题——分离控制和逻辑。
所谓控制就是对程序流转的与业务逻辑无关的代码或系统的控制(如多线程、异步、服务发现、部署、弹性伸缩等),
所谓逻辑则是实实在在的业务逻辑,是解决用户问题的逻辑。
控制和逻辑构成了整体的软件复杂度,有效地分离控制和逻辑会让你的系统得到最大的简化
复杂系统的问题: 需求、环境和技术的不断变化,涉及的因素和角色众多,各种因素之间互相关联
边界的选择取决于你想要了解的信息和出于何种目的进行考虑
系统思维--应对问题的复杂性:将问题分解成更小的组成部分的过程,同时意识到每个部分对整个系统的影响
系统的工具:要素、连接和目标 全局、动态、关联 适应力、自组织、层次性
存量、流量和反馈回路
有限理性 时间延迟
系统论--信息论--控制论
耗散结构论、协同论、突变论称为“新三论”
耗散结构论:
自组织: 是现代非线性科学和非平衡态热力学: 单元自律 短程通讯 微观决策
突变论: 稳定状态进入不稳定状态 不稳定状态进入另一种稳定状态
内存与程序运行中的报错
寄存器--堆heap 和栈stack
stack 栈主要用于存储函数调用时需要的各种信息,以及函数执行过程中产生的临时数据。栈的特点是高效的内存分配和释放,但是大小有限,
函数返回地址-函数的参数-局部变量
1. 局部变量:在函数内部声明的局部变量会被存储在栈上
纯虚函数
C++可以通过抽象类(Abstract Class)和纯虚函数(Pure Virtual Function)来模拟接口的概念
没有直接提供接口关键字
C++标准库本身并没有直接提供像Java或C#那样的“接口”关键字。然而,
抽象类(Abstract Class)
C++语言中没有抽象类的概念 C++中通过纯虚函数实现抽象类。
纯虚函数(Pure Virtual Function)
纯虚函数是没有函数体的虚函数,它强制派生类(子类)实现该函数
在C++中,这通过创建一个包含纯虚函数的抽象类来实现。
抽象类通常用作基类,派生类继承它并提供纯虚函数的实现。
仓颉编程
虚拟机监视器(Hypervisor)
Hypervisor的类型和特点
Hypervisor有两种类型:类型1(裸机)和类型2(宿主机)。类型1 Hypervisor直接运行在硬件之
定义操作符函数时需要在 func 关键字前面添加 operator 修饰符;
操作符函数的 参数个数需要匹配对应操作符的要求;
操作符函数只能定义在 class、interface、struct、enum 和 extend 中;
操作符函数具有实例成员函数的语义,所以禁止使用 static 修饰符;
操作符函数不能为泛型函数。
eg: public operator func -(): Point { Point(-x, -y) }
在Java中,运算符是不能被重载的
没有运算符重载,但却将基础非常易用的运算符进行了重载
python重载: __add__(self, other) _sub__(self, other) __mul__(self, other) _truediv__(self, other) __str__(self):
绑定(binding)和重绑定(rebinding)
参考
c++类——类与类之间的关系 https://blog.csdn.net/xiaohei07/article/details/131676336
架构整洁之道
https://github.com/puge-up/programming-cpp/tree/main
https://bbs.huaweicloud.com/blogs/397606
C++编译器合成默认构造函数的真相 https://bbs.huaweicloud.com/blogs/321795
C++编译器自动生成的函数 https://www.cnblogs.com/islch/p/16143768.html
标签:函数,--,模式,运算符,对象,C++,重载,设计模式,构造函数
From: https://www.cnblogs.com/ytwang/p/18595512