- 博客(47)
- 收藏
- 关注
原创 8、构造型模式——组合模式(Composite)
1、定义使用组合模式可以将对象组合成树状结构,并且能像使用独立对象一样使用它们。2、前言问题:例如你有两类对象:产品和盒子。一个盒子中可以包含多个产品或者几个较小的盒子。这些小盒子中同样可以包含一些产品或者更小的盒子。假设你希望在这些类的基础上开发一个订购系统。从下图可以看出,订单中可能包括各种产品,这些产品放置在盒子中,然后又被放入一层又一层更大的盒子总。整个结构看上去像是一棵倒过来的树。解决方案:组合模式建议使用一个通用结构来与「产品」和「盒子」进行交互,并且在该接口中声明一个计
2022-03-31 16:44:42
680
原创 7、构造型模式——桥接模式(Bridge)
定义桥接模式(Bridge Pattern):可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。前言背景:假如你有一个几何形状(Shape)类, 从它能扩展出两个子类: 圆形(Circle)和方形(Square)。你希望对这样的类层次结构进行扩展以使其包含颜色, 所以你打算创建名为红色(Red)和蓝色(Blue)的形状子类。但是,由于你已有两个子类,所以总共需要创建四个类才能覆盖所有组合,例如蓝色圆形(BlueCircle)和红色方形(RedSq
2022-03-30 17:17:59
554
原创 6、构造型模式——适配器模式(Adapter)
1、动机让接口不兼容的对象能够相互合作。小栗子:你在开发一款股票市场监测程序,它会从不同来源下载 XML 格式的股票数据,但现在想在程序中整合一个只兼容JSON格式的函数库,怎么办?解决方案:创建一个适配器。这是一个特殊的对象,能够转换对象接口,使其能与其他对象进行交互。2、结构适配器模式包含如下角色:Target:目标抽象类Adapter:适配器类Adaptee:适配者类Client:客户类适配器模式有对象适配器和类适配器两种实现:对象适配器和类适配器。2.1
2022-03-29 21:12:42
460
原创 5、创建型模式——单例模式(Singleton)
1、动机对于系统中的某些类来说,只有一个实例化对象很重要。普通类的对象,既可以叫对象,也可以叫实例化对象(实例)抽象类是不可以被实例化的,那它的对象就不能叫实例化对象,只能叫对象。如何保证一个类只有一个实例化对象且这个实例化对象易于被访问呢?定义一个全局变量可以确保实例化对象随时都可以被访问,但不能防止我们实例化多个对象。好的解决办法:让类自身负责保存它的唯一实例化对象。这个类可以保证没有其他实例化对象被创建,并且它可以提供一个访问该实例化对象的方法。2、实现方式a)在类中添加一个私
2022-03-29 16:26:05
902
原创 4、创建型模式——原型模式(Prototype)
意图原型模式(Prototype)是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。结构原型式的结构包含以下几个角色:抽象原型类(AbstractPrototype):声明克隆clone自身的接口具体原型类(ConcretePrototype):实现clone接口客户端(Client):客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象实例代码Prototype.h:#ifndef PROTOTYPE_H_#define PROTOTYP
2022-03-28 21:14:00
487
原创 3、创建型模式——建造者模式
动机无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者模式对其进行设计与描述。建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。在软件开发中,也存在大量类似汽车一样的复杂对象,它们拥有一系列成员属性:这
2022-03-27 15:23:07
713
原创 2、创建型模式——抽象工厂模式
为什么需要抽象工厂模式?有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。类图抽象工厂模式包含如下角色:AbstractProduct:抽象产品Product:具体产品AbstractFactory:抽象工厂ConcreteFactory:具体工厂时序图代码AbstractProduct.h#ifndef ABSTRACT_PRODUCT_H_#define ABSTRACT_PRODUCT_H_#include <string>//
2022-03-24 22:17:12
193
原创 1、创建型模式——简单工厂模式
简单工厂模式UML图产品(Product)将会对接口进行声明。对于所有由创建者及其子类构建的对象,这些接口都是通用的。具体产品(Concrete Products)是产品接口的不同实现。创建者(Creator)类声明返回产品对象的工厂方法。该方法的返回对象类型必须与产品接口相匹配。 你可以将工厂方法声明为抽象方法,强制要求每个子类以不同方式实现该方法。或者,你也可以在基础工厂方法中返回默认产品类型。注意,尽管它的名字是创建者,但他最主要的职责并不是创建产品。一般来说,创建者类包含一些与产品相关的核
2022-03-21 21:15:50
340
原创 为什么要使用动态存储空间?
1. c++中内存分为两个部分:栈:函数内部声明的所有 变量 都在 栈内存 中。堆:程序中 未使用 的内存,在程序 运行时 用于 动态分配内存。2. 为什么要使用动态分配内存?以实例化一个类为例://第1种:直接定义法 ----->直接将a放入栈区(局部变量,大小受限,自动释放)A a;//第2种:动态内存分配法-----> 堆区分配一块内存,用指针a去指向这块内存。(动态内存,大小任意,手动释放)A* a;a = new A();3. 动态分配内
2022-03-15 17:25:50
807
原创 typedef常见用法
一、typedef的作用1、typedef的一个重要用途是定义机器类型无关的类型。例如在适用long double的目标机器上定义名为“REAL”的数据类型:typedef long double REAL;如果在不适合long double的机器上运行相关代码,只需要修改对应的typedef语句。例如:typedef double REAL;//或者typedef float REAL;2、使用typedef为现有类型创建别名,给变量定义一个易于记忆且意义明确的新名字例如:type
2022-03-15 17:15:43
1811
原创 C++命令空间namespace的作用和使用解析
命令空间的作用?命名空间可为附加信息来区分不同库中相同名称的函数、类、变量等。本质上,命名空间就是定义了一个范围。例如:一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。定义命名空间#include<iostream>using namespace std;namespace first_space{ // 第一个命名空间 void func(){...}}namespace second_space{// 第二个
2022-03-15 17:13:20
314
原创 Visual Studio的编译过程
VS上点击编译准备生成exe文件时,编译器做了两步工作:① 将每个 .cpp 和 相应的 .h 文件编译成 obj 文件。② 将工程中的所有 obj 文件进行链接,生成最终的 .exe文件。编译时的错误:主要是语法错误。链接时的错误:主要是重复定义变量等。编译单元:指在编译阶段生成的每个 obj 文件。一个obj文件就是一个编译单元。一个 .cpp 和它相应的 .h文件共同组成了一个编译单元。一个工程文件由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等。声明和定义
2022-03-15 17:03:08
6285
原创 将文件间的编译依存关系降至最低
结论:避免大量依赖性编译的解决方案是,在头文件中用 class声明 外来类,用指针或引用来代替变量的声明;在CPP文件中包含外来类的头文件。好处:如果A.h发生改变,所有包含类A对象的文件都要重新编。在B.cpp中包含A.h的好处是:所有用到类B对象的文件都不用重新编译。// A.hclass A{ funcA();};// A.cppA的实现// B.hclass A;class B{ A* xx; //用A的指针来替代变量的声明};// B.cpp
2022-03-15 17:00:38
1337
1
原创 理解C/C++函数指针
一、函数的类型与地址看看下面典型的函数:int func(){ return 5;}func的函数类型:无参且返回类型为int 。代码表示:int (*someotherfunc)()如果函数有两个形参且返回值为bool型呢?函数类型该怎么用代码表示?bool (*someotherfunc)(int,int)和变量一样,函数在内存中有固定的地址。函数的实质也是内存中一块固定的内存。std::cout<<func; //008A1483std::
2022-03-15 16:56:39
969
原创 类之间的六种静态关系和类图实现(c++)
类之间的六种静态关系和类图实现(c++)类图的表示方法:每个类分为三层,最顶层的为类名,中间层的为属性,最底层的为方法。属性 的表示方式为:【可见性】【属性名称】:【类型】={缺省值,可选}方法 的表示方式为:【可见性】【方法名称】(【参数列表】):【类型】可见性 都是一样的:"-“表示private、”+“表示public、”#"表示protected。① 继承(generalization)继承:继承是最能体现面向对象代码复用的类关系。“is a”例如 duck “is a
2022-03-15 16:52:32
2977
原创 空洞卷积的理解
一、空洞卷积的本质空洞卷积(dilated convolution)在标准卷积里注入空洞,增加感受野(reception filed)。空洞卷积比普通卷积多了个超参数称为dilation rate,指的是kernel的间隔数量。普通卷积的dilation rate为1。普通卷积:空洞卷积:二、空洞卷积的优点关于传统深度卷积的up-sampling和pooling layer的缺点2.1 up-sampling(放大特征图)up-sampling(放大特征图):线性插值、反卷积(decon
2021-09-06 20:31:03
2423
原创 C++中为什么不能将全局变量定义在头文件中?
一、什么是全局变量?C++中全局变量一般指定义在函数体外的变量。全局变量按可访问性可分为外部变量和内部变量。二、内部变量和外部变量的定义内部变量:使用了static关键字修饰的全局变量。它的可访问范围(作用域)被限定在本源文件所在的链接文件模块中,不能被其他文件模块引用。外部变量:没有被static修饰的全局变量。其他文件模块可以通过extern关键字引用该全局变量并访问。三、全局变量放在头文件中会出现哪些问题?问题一:对内部变量来讲,每个include该头文件的文件模块中都会单独为这个内部
2021-09-06 20:30:26
5354
原创 C++中explicit关键字详解
C++中的explicit关键字只能用于修饰 只有一个参数的类构造函数。explicit的作用:表明该构造函数是 显式 的,而非隐式的。跟explicit相对应的另一个关键字是implicit,意思是隐藏的。类构造函数默认情况下即声明为implicit(隐式)。class CxString{ public: CxString(int size) { _size = size; //string的预设大小
2021-08-31 11:35:40
939
原创 C++异常
一、C++异常处理入门程序常见的三种错误:语法错误、逻辑错误和运行错误。语法错误:编译和链接阶段就能发现。逻辑错误:代码没问题,但不能达到预期目标,可以通过调试来解决。运行错误:在运行期间发生的错误,例如除数为 0、内存分配失败、数组越界、文件不存在等。C++异常机制就是为解决运行时错误而引入的。捕获异常捕获异常的语法为:try{ // 可能抛出异常的语句}catch(exceptionType variable){ // catch 告诉 try:你去检测一下程序有没
2021-08-31 11:34:47
304
原创 C++命令空间namespace的作用和使用解析
1、命令空间的作用?命名空间可最为附加信息来区分不同库中相同名称的函数、类、变量等。本质上,命名空间就是定义了一个范围。例如:一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。2、定义命名空间#include<iostream>using namespace std;namespace first_space{ // 第一个命名空间 void func(){...}}namespace second_space{/
2021-08-31 11:32:59
1321
2
原创 19、C++11 shared_ptr智能指针
C++98/03 标准中,支持使用 auto_ptr 智能指针来实现堆内存的自动回收;C++11 新标准在废弃 auto_ptr 的同时,增添了 unique_ptr、shared_ptr 以及 weak_ptr 这 3 个智能指针来实现堆内存的自动回收。shared_ptr智能指针每种智能指针都以类模板的方式实现。shared_ptr<T>的定义位于<memory>头文件,并位于std命名空间中。// 每次使用加这两行代码#include<memory>.
2021-08-31 11:27:20
217
原创 18、C++11完美转发及实现方法
什么是完美转发?它指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。完美,表示能保证被转发参数的左、右值属性不变。“不完美“函数举例:template<typename T>void function(T t) // 非引用,形参会对实参进行拷贝。{ // 对于函数内部来说,t有自己的名称,也可以获取它的存储地址,因此它永远都是左值。 otherdef(t);}传递给 otherdef() 函数的参数 t 永远都是
2021-08-31 11:25:07
1079
原创 17、C++11 move()函数:将左值强制转换为右值
移动构造函数的调用时机是:用同类的右值对象初始化新对象。当前类的左值对象(有名称,能获取其存储地址的实例对象)初始化同类对象时,使用move() 函数可以调用移动构造函数。move( )功能:将某个左值强制转化为右值。//函数会返回 arg 对象的右值形式move(arg) //arg 表示指定的左值对象#include <iostream>using namespace std;class movedemo{public: movedemo():num(new in
2021-08-31 11:24:11
335
原创 16、C++11移动构造函数
本节主要讲解移动语义的含义以及实现它的方式。C++ 98/03 标准中,想用其他对象初始化一个同类的新对象,只能借助拷贝构造函数。(原理是为新对象复制一份和其他对象一模一样的数据)#include<iostream>using namespace std;class Demo{public: Demo():num(new int(10)) { cout<<"construct"<<endl; } //拷贝构造函数
2021-08-31 11:23:03
453
原创 15、C++11右值引用
右值引用只不过是一种新的 C++ 语法,真正理解起来有难度的是基于右值引用引申出的 2 种 C++ 编程技巧,分别为移动语义和完美转发。本节先讲什么是右值引用,以及它的基本用法。C++左值和右值左值(lvalue):“loactor value”,可意为存储在内存中、有明确存储地址(可寻址)的数据。右值(rvalue):”read value“,指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。判断某个表达式是左值还是右值,最常用的有以下 2 种方法(只使用于大部分场
2021-08-31 11:21:57
157
原创 13、C++11 constexpr:验证是否为常量表达式
所谓常量表达式,指的就是由多个(≥1)常量 组成的表达式。如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。常量表达式一旦确定,其值将无法修改。// 1)int url[10];//正确// 2)int url[6 + 4];//正确// 3)int length = 6;int url[length];//错误,length是变量非常量表达式只能在程序**运行阶段**计算出结果;而常量表达式的计算往往发生在程序的**编译阶段**。 常量表达式的计算往往发生在程
2021-08-31 11:20:34
297
原创 12、C++11 for循环使用注意事项
当使用 for 循环遍历某个序列时,无论该序列是普通数组、容器还是用{ }大括号包裹的初始化列表,遍历序列的变量都表示的是当前序列中的各个元素。并不是迭代器。基于范围的 for 循环可以遍历普通数组、string字符串、容器以及初始化列表。除此之外,for 循环冒号后还可以放置返回 string 字符串以及容器对象的函数。但是不能遍历用指针表示的数组。当基于范围的 for 循环遍历的是某函数返回的 string 对象或者容器时,整个遍历过程中,函数只会执行一次。- ```c++.
2021-08-31 11:16:46
829
原创 C++对象模型(整理)
C++对象模型1、何为C++对象模型?C++对象模型可以概括为以下2部分:① 语言中直接支持面向对象程序设计的部分面向对象程序设计部分:如构造函数、析构函数、虚函数、继承(单继承、多继承、虚继承)、多态等。② 对于各种支持的底层实现机制在C++类中有两种数据成员、三种成员函数:两种数据成员:static、nonstatic。三种成员函数:static、nonstatic、virtual。代码举例说明://base.h#pragma once#include<i
2021-06-25 09:01:39
3653
2
原创 C++11:(十)C++11非受限联合体(union)
在 C/C++ 中,联合体(Union)是一种构造数据类型。在一个联合体内,我们可以定义多个不同类型的成员,这些成员将会共享同一块内存空间。老版本的 C++ 为了和C语言保持兼容,对联合体的 数据成员的类型 进行了很大程度的限制,联合体成员必须是POD类型,因此 C++11 取消了这些限制。1、C++11 允许非 POD 类型POD 类型一般具有以下几种特征(包括 class、union 和 struct等):没有用户自定义的构造函数、析构函数、拷贝构造函数和移动构造函数。不能
2021-06-18 10:44:25
717
原创 C++11:(九)C++11 lambda匿名函数
lambda是匿名函数,简单地理解就是没有名称的函数。lambda匿名函数的定义定义一个 lambda 匿名函数很简单,可以套用如下的语法格式:[外部变量访问方式说明符] (参数) mutablle noexcept/throw() -> 返回值类型{ 函数体;}其中各部分的含义分别为:① [外部变量方位方式说明符][]方括号用于向编译器表明当前是一个 lambda 表达式,其不能被省略。在方括号内部,可以注明当前 lambda 函数的函数体中可以使用哪些==“外
2021-06-18 10:42:51
246
原创 C++11:(八)C++11列表初始化(统一了初始化方式)
int i_arr[3] { 1, 2, 3 }; //普通数组int i_arr[3]={ 1, 2, 3 }; // {}前面的等于号对初始化行为没有影响。(算直接初始化,不算拷贝初始化)//new操作也可以用int *a = new int{1,2,3};//函数返回值也可以用return {1,2,3};...
2021-06-18 10:39:57
183
原创 C++11:(七)C++11支持函数模板的默认模板参数
C++98/03:类模板可以有默认的模板参数template<typename T,typename U = int, U N = 0>struct Foo{ //... };但不支持函数的默认模板参数:template <typename T = int> // error in C++98/03: default template argumentsvoid func(){ // ...}C++11:上面的func函数可以编译通过。
2021-06-18 10:38:55
315
原创 C++11:(六)C++11使用using定义别名(替代typedef)
C++98/03:在 C++ 中可以通过 typedef 重定义一个类型:typedef unsigned int uint_t;但是无法重定义一个模板。所以不得不这么写:template<typename Val>struct str_map{ typedef map<string, Val> type;}//使用str_map<int>::type map1; //必须加个str_map<int>外敷类C++11:using
2021-06-18 10:37:13
375
原创 C++11:(五)C++11对模板实例化中连续右尖括号>>的改进
C++98/03:以前模板实例化的连续两个右尖括号(>>)会被编译器解释成 右移操作符,而不是 模板参数表的结束。template<typename T>struct Foo{ typedef T type;};template <typename T>class A{ // ...};int main(){ Foo<A<int>>::type xx; //编译出错,要写成 Foo<
2021-06-18 10:36:19
594
原创 C++11:(四)C++返回值类型后置
C++98/03:在泛型编程中,可能需要通过参数的运算来得到返回值的类型。template<typename R, typename T, typename U>R add(T t, U u){ return t+u;}int a = 1;float b = 2.0;auto c = add<decltype(a+b)>(a,b); //我们想获得返回值类型,得通过decltype显式推导出返回值类型,比较麻烦。C++的返回值是前置语法,在返回值定义
2021-06-18 10:34:51
578
原创 C++11:(三)C++ auto和decltype的区别
语法格式不同:auto varname = value; //auto的语法格式decltype(exp) varname [= value]; //decltype的语法格式对cv限定符的处理:const 关键字用来表示数据是只读的,也就是不能被修改;volatile 和 const 是相反的,它用来表示数据是可变的、易变的,目的是不让 CPU 将数据缓存到寄存器,而是从原始的内存中读取。推导变量类型时,decltype 会 保留 cv 限定符,而 auto 有 可能会去掉
2021-06-18 10:33:30
173
原创 C++11:(二)decltype类型推导
decltype的功能和auto相同,都用来在编译时期进行自动类型推导。两者区别如下:auto varname = value;decltype(exp) varname = value;auto根据=右边的初始值value推导出变量的类型。decltype根据exp表达式推导出变量类型,跟=右边的初始值value没有关系。举例:decltype(10.8) x = 5.5; //x 被推导成了 doubledecltype(x+100) y; //y 被推导成了 double
2021-06-18 10:32:34
206
原创 C++11:(一)auto类型推导
C++11顺应大趋势,让编译器支持自动类型推导。C++11 使用 auto 关键字来支持自动类型推导。auto name = value;auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。使用 auto 类型推导的变量必须初始化。auto的高级用法:auto 除了可以独立使用,还可以和某些具体类型混合使用,这样 auto 表示的就是“半个”类型,而不是完整的类型。int x = 0;auto *p1 = &x; //p1 为 int *,auto 推导为 in
2021-06-18 10:31:27
352
转载 天池广东工业智造大数据创新大赛--铝型材表面瑕疵识别 --top1方案
天池广东工业智造大数据创新大赛--铝型材表面瑕疵识别 --top1方案 2018年广东省人民政府联合阿里巴巴集团共同启动“广东工业智造大数据创新大赛”,旨在通过数据开放召集全球众智,将重点围绕工业制造大数据展开,以应用为导向,聚集全球顶级人才,发掘全球先进的智能制造应用成果,为政府下一步产业引进和招商引资提供辅助决策,促进广东智能制造产业发展。大赛分智能算法赛和应用创新赛2大赛场。智能算法赛以“铝型材表面瑕疵识别...
2020-11-28 17:33:44
1104
原创 Repulsion loss的详细理解
本文由同济大学和北京大学合作发表于CVPR2018,聚焦于loss层面,为遮挡情况下的行人检测问题提供了一种行之有效的解决方案。论文:https://arxiv.org/abs/1711.07752一、问题提出1.行人遮挡会造成什么问题当我们在做行人检测时,人与人之间会存在互相遮挡。遮挡会造成2个问题:1.设红色框为目标框T(man)的预测框P,旁边也有个真实框B(woman),我们的P可能会被往B去移动(shift)。2.检测器对NMS的阈值的选取更为敏感。如果NMS阈值选取过小,周围的目标.
2020-09-28 16:22:06
5879
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人