C++
勇士后卫头盔哥
这个作者很懒,什么都没留下…
展开
-
经典面试题
1如何判断一个变量是否为指针1.补充个小知识点C++中仍然支持C语言中的可变参数函数C++编译器的匹配优先级为普通函数>函数模板>变参函数代码如下:#include <iostream>#include <string>#include <typeinfo>using namespace std;/*class Test{ ...原创 2020-04-20 11:44:19 · 91 阅读 · 0 评论 -
那些奇奇怪怪的写法
1template <class T>class Test{ public: Test(T t){}}template <class T>void func(T a[],int len){}关键字template意味着我们要定义一个模板,那定义模板肯定要有泛指类型,那么泛指类型在哪里呢,T就是我们要的泛指类型,那为什么T前面是关键字class而不是...原创 2020-04-12 14:26:04 · 245 阅读 · 0 评论 -
类型识别
在面向对象中有一个原则就是赋值兼容性原则,就是一个子类对象完完全全可以当作一个父类对象来使用,可能会出现下面的情况,静态类型指的是变量自身的类型,动态类型指的是指针所指向对象的实际类型-基类指针指向子类对象-基类引用成为子类对象的别名Base* p = new Derived();Base& r = *p;Base为静态类型 Derived为动态类型如以下代码是个非常危险的...原创 2020-04-12 13:01:44 · 104 阅读 · 0 评论 -
打造一个异常类
现在C++库必然包含充要的异常类族,异常类族是数据结构类所依赖的"基础设施", 如下图是该异常类族的类图,顶层的类是一个抽象类,它是不能定义对象的,只能用来被继承,从左向右的异常类分别为计算异常,空指针异常,越界异常,内存不足异常,参数错误异常,顶层抽象父类的接口定义:class Exception{ public: Exception(const char *message);...原创 2020-03-28 13:40:23 · 76 阅读 · 0 评论 -
C/C++异常处理
异常概念程序在运行过程中可能产生异常,异常是程序运行时可预料的执行分支,Bug是程序错误,是不可被预期的运行方式C语言处理异常的方式void func(...){ if(判断是否产生异常) { 正常情况代码逻辑; } else { 异常情况代码逻辑; }}例子:#include <iostream>#include <s...原创 2020-03-22 15:08:01 · 318 阅读 · 0 评论 -
单例模式
在架构设计时,某些类在整个系统生命期最多只有一个对象存在,这个时候单例模式的需求就发展出来,那如何定义一个类,使得这个类最多只能创建一个对象呢,思路如下1.将构造函数的访问属性设置为private(外界无法创建对象)2.定义instance并初始化为NULL3.当需要使用对象时,访问instance的值空值:创建对象,并用instance标记非空值:返回instance标记的对象例子:...原创 2020-03-21 21:31:19 · 81 阅读 · 0 评论 -
智能指针类模板
智能指针模板的前言之前的文章中我们已经介绍过了智能指针,智能指针在本质上是一个对象这个对象可以像原生的指针一样来使用,智能对象的类通过重载的技术,将指针相关的操作符进行了重载,优化后的智能指针类模板可以用来定义任意类型的指针,性能大大提升了智能指针的意义现代C++开发库中最重要的类模板之一C++中自动内存管理的主要手段能够在很大程序上避开内存相关的问题STL中的智能指针auto_...原创 2020-03-21 00:04:51 · 132 阅读 · 0 评论 -
数组类模板
模板参数可以是数值型参数(非类型参数)template <typename T,int N>void func(){ T a[N]; //使用模板参数的数值型参数定义局部数组}func<double,10>();数值型模板参数的限制-变量不能作为模板参数-浮点数不能作为模板参数-类对象不能作为模板参数…本质:模板参数是再编译阶段被...原创 2020-03-20 17:05:18 · 230 阅读 · 0 评论 -
类模板
类模板的简述之前的函数模板文章中我们将泛型的思想应用到函数中,现在我们将泛型的思想应用于类,类模板就是为数据结构诞生的,一些类主要用于存储和组织数据元素,类中数据组织的方式和数据元素的具体类型无关,如:数组类,链类,Stack类,Queue类…C++中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能,类模板在使用时只能显示指定类型C++中的类模板—以相同...原创 2020-03-19 14:55:08 · 194 阅读 · 0 评论 -
函数模板
对于变量的值的交换我们可以采用函数或者宏定义的方法,它们之间有什么不同呢?下面的代码采用函数的方法#include <iostream>#include <string>using namespace std;void Swap(double& a,double& b){ double c = a; a = b; ...原创 2020-03-18 17:36:45 · 116 阅读 · 0 评论 -
抛弃的多重继承
C++语言是支持多继承的,这在java,C#是支持不允许多继承的一个子类可以拥有多个子类子类拥有所有父类的成员变量子类继承所有父类的成员函数子类对象可以当作任意父类对象使用语法规则:class Derived: public Base A, public Base B, public Base C,{};例子:#in...原创 2020-03-17 22:00:39 · 77 阅读 · 0 评论 -
C++对象模型
一个C++对象仅仅代表类中成员变量的集合, 运行时的对象退化为结构体的形式-所有成员变量在内存中依次排布-成员变量间可能存在内存空隙-可以通过内存地址直接访问成员变量-访问权限关键字在运行时失效例子:sice@sice:~$ cat a.cpp#include <iostream>#include <string>using namespace std;...原创 2020-03-17 20:00:00 · 98 阅读 · 0 评论 -
抽象类和接口
面向对象中的抽象类可用于表达现实世界中的抽象概念,是一种只能定义类型,而不能产生对象的类,**就是说抽象类不能定义对象,但是能定义指针,**只能被继承并重写相关函数,抽象类用于抽象出子类的共同特征,提高代码的架构能力,最直接的特性就是相关函数没有完整的实现,但是C++语言中没有抽象类的概念,只能通过纯虚函数实现抽象类,注意这里是纯虚函数和我们之前说的虚函数还有差别,纯虚函数是指只定义原型的成员函数...原创 2020-03-16 23:14:30 · 67 阅读 · 0 评论 -
多态的概念和意义
在之前同名覆盖引发问题的那一篇文章,我们说过了编译器在同名覆盖中所作的行为并不是我们期望的行为,面向对象中期望的行为是根据实际的对象类型判断如何调用重写函数,期望做到父类指针(引用)指向父类对象则调用父类中定义的函数,指向子类对象则调用子类中定义的重写函数,不要根据指针类型去调用,要根据指针指向的对象类型去调用,现在我们引入多态的概念要实现多态,就需要用到virtual关键字对多态进行支持,被...原创 2020-03-14 20:57:54 · 500 阅读 · 0 评论 -
同名覆盖引发的问题
在C++中,子类对象可以当作父类对象使用子类对象可以直接赋值给父类对象子类对象可以直接初始化父类对象父类指针可以直接指向子类对象父类引用可以直接引用子类对象先来看一个例子:#include <iostream>#include <string>using namespace std;class Parent{public: int mi;...原创 2020-03-14 19:13:07 · 83 阅读 · 0 评论 -
父子类间的冲突
父子类中同名成员的规则子类可以定义父类中的同名成员子类中的成员将隐藏父类中的同名成员父类的同名成员依然存在于子类中通过作用域分辨符(::)访问父类中的同名成员例子:#include <iostream>#include <string>using namespace std;class Parent{ public: int mi; Pare...原创 2020-03-14 11:39:37 · 116 阅读 · 0 评论 -
继承中的构造和析构
子类的构造函数必须对继承而来的成员进行初始化1.直接通过初始化列表或者赋值的方式进行初始2.调用父类构造函数进行初始化父类构造函数在子类中的调用方式1.默认调用.适用无参构造函数和使用默认参数的构造函数2.显示调用.通过初始化列表进行调用,适用于所有父类的构造函数例子:class Child : public parent{ public: Child()/*隐式调用,调用...原创 2020-03-14 00:22:53 · 145 阅读 · 0 评论 -
不同的继承方式
冒号(:)表示继承关系,Parent表示被继承的类,public的意义是什么,是否可以替换成private或者protected?答案是肯定的class Parent{};class Child : public Parent{};C++中支持三种不同的继承方式-public 继承父类成员在子类中保持原有访问级别-private 继承父类成员在子类中变成私有成员-prot...原创 2020-03-13 12:04:01 · 120 阅读 · 0 评论 -
继承中的访问级别
继承的概念之前的文章已经提及了,那么子类是否可以直接访问父类的私有成员呢,答案是否定的例子:#include <iostream>#include <string>using namespace std;class Parent{ private: int mv; public: Parent() { mv = 100; }...原创 2020-03-12 17:20:56 · 138 阅读 · 0 评论 -
继承的概念和意义
类和类之间的关系可以是组合的关系,比如电脑由CPU,内存,硬盘,显卡等待组成,看一个例子#include <iostream>#include <string>using namespace std;class Memory{public: Memory() { cout << "Memory()" << ...原创 2020-03-11 10:59:33 · 76 阅读 · 0 评论 -
类型转化函数
在我们之前学的C语言中标准数据类型之间会进行隐式类型转化,小类型可以转化到大类型,转化规则如下:例子:#include <iostream>#include <string>using namespace std;int main(){ short s = 'a'; unsigned int ui = 2000; int i = -3000; ...原创 2020-03-10 22:15:23 · 468 阅读 · 0 评论 -
前置操作符和后置操作符
++操作符可以被重载全局函数和成员函数均可以进行重载重载前置++操作符不需要额外的参数重载后置++操作符需要一个Int类型的占位参数来看一个例子#include <string>#include <iostream>using namespace std;class Test{ int mValue;public: Test(int i...原创 2020-03-09 20:19:48 · 168 阅读 · 0 评论 -
逗号操作符
逗号操作符(,)可以构成逗号表达式逗号表达式用于将多个子表达式连接为一个表达式逗号表达式的值为最后一个子表达式的值逗号表达式的前N-1个子表达...原创 2020-03-09 15:36:30 · 114 阅读 · 0 评论 -
逻辑操作符
逻辑运算符的原生语义操作数只有两种值(true 和 false)逻辑表达式不用完全计算就能确定最终值最终结果只能是true或者false原创 2020-03-09 13:18:22 · 130 阅读 · 1 评论 -
智能指针
我们的项目中就难避免的就是内存泄漏,内存泄漏就是动态申请堆空间,指针无法控制所指堆空间的生命周期,用完后不归还,有的编程语言有垃圾回收的机制,但是我们的C++语言没有垃圾回收机制,为了避免内存泄漏,我就需要一个特殊的指针,指针生命周期结束时主动释放堆空间,而且这一片堆空间最多只能由一个指针标识,还要避免指针运算和指针比较,,所以我们要提出一个解决方案满足上述要求方案:重载指针特征操作符(-&g...原创 2020-03-08 13:46:53 · 73 阅读 · 0 评论 -
经典问题(2)
什么时候需要重载赋值操作符,编译器是否提供默认的赋值操作?编译器为每个类默认重载了赋值操作符默认的赋值操作符仅完成浅拷贝当需要进行深拷贝是必须重载赋值操作符赋值操作符与拷贝构造函数有相同的存在意义先来看一个例子:#include <iostream>#include <string>using namespace std;class Test{ p...原创 2020-03-08 10:56:17 · 68 阅读 · 0 评论 -
函数对象分析
函数对象:使用具体的类对象取代函数该类的对象具备函数调用的行为构造函数指定具体数列项的起始位置多个对象相互独立的求解数列项先来看一个实现一个函数可以获得斐波那契数列每项的值例子:#include <iostream>#include <string>using namespace std;int fib(){ static int a0 =...原创 2020-03-07 23:36:13 · 90 阅读 · 0 评论 -
数组操作符的重载
String类最大限度的考虑了C字符串的兼容性,可以按照使用C字符串的方式使用string对象,也就是可以通过数组下标访问String对象的单个字符,例子#include <iostream>#include <sstream>#include <string>using namespace std;int main(){ string s = ...原创 2020-03-07 11:34:22 · 131 阅读 · 0 评论 -
C++字符串类
字符串我们在C语言中其实已经学习过了,在C语言中学习字符串我们用的是另一个概念,字符数组,也就是在C语言中没有真正意义上的字符串,用字符数组模拟字符串,C++语言直接支持C语言的所有概念,C++语言中没有原生的字符串类型,但是C++标准库提供了string类型string直接支持字符串连接string直接支持字符串的大小比较string直接支持子串查找和提取string直接支持字符串的插入...原创 2020-03-07 10:13:55 · 166 阅读 · 0 评论 -
C++标准库
我们之前说过操作符重载的概念,接下来我们来写一个例子:#include <stdio.h>class Console{ public: void operator << (int i) { printf("%d",i); }};Console cout;int main(void){ cout<<1;//t.operat...原创 2020-03-06 16:10:00 · 170 阅读 · 1 评论 -
操作符重载的概念
我们先来看下面这个例子是否能编译通过实现复数的相加#include <stdio.h>class Complex{ public: int a; int b;};int main(){ Complex c1 = {1,2}; Complex c2 = {3,4}; Complex c3 = c1 + c2; return 0;}...原创 2020-03-06 15:57:31 · 109 阅读 · 0 评论 -
类中的函数重载
小知识点:函数重载的本质为相互独立的不同函数C++中通过函数名和函数参数确定函数调用无法直接通过函数名得到重载函数的入口地址函数重载必然发生在同一个作用域中构造函数,普通成员函数,静态成员函数都可以进行重载,全局函数位于一个全局的命名空间中,而成员函数位于类里面,它们的作用域已经不样了,所以它们之间不能构成重载例子:#include <stdio.h>class Te...原创 2020-03-04 15:06:15 · 191 阅读 · 0 评论 -
友元
友元是C++中的一种关系,友元关系发生在函数与类之间或者类与类之间,友元关系是单项的,不能传递友元的用法在类中以friend关键字声明友元类的友元可以是其他类或者具体函数友元不是类的一部分友元不受类中访问级别的限制友元可以直接访问具体类的所有成员小栗子:class Point{ double x; double y; friend void func(Point&am...原创 2020-03-04 11:11:42 · 81 阅读 · 0 评论 -
二阶构造模式
对于构造函数而言,它没有返回值则我们无法判断构造函数是否成功,构造函数执行完并不意味初始化逻辑成功,构造函数能决定的只是对象的初始状态,而不是对象的诞生,简单的处理,我们可以加入一个成员变量来辨别:#include <stdio.h>class Test{ int mi; int mj; bool mStatus;public: Test(int...原创 2020-03-03 17:30:06 · 77 阅读 · 0 评论 -
类的静态成员变量
通过对象名能够访问public成员变量,每个对象的成员变量都是专属的,成员变量不能再对象之间共享,先来看一个例子:#include <stdio.h>class Test{private: int mCount;public: Test() : mCount(0) { mCount++; } ~Test() {...原创 2020-03-02 16:47:10 · 151 阅读 · 0 评论 -
经典问题
第一个问题当程序存在多个对象的时候,如何确定这些对象的析构顺序?单个对象创建时构造函数的调用顺序调用父类的构造过程调用成员变量的构造函数(调用顺序与声明顺序相同)调用类自身的构造函数析构函数与对应构造函数的调用顺序相反多个对象析构时析构顺序与构造顺序相反,比如构造对象A,B,C,析构就是C,B,A例子:#include <stdio.h>class Membe...原创 2020-03-02 15:03:43 · 92 阅读 · 0 评论 -
临时对象
临时对象在很多C++的书籍中都不会引入,先看一个例子:#include <stdio.h>class Test { int mi;public: Test(int i) { mi = i; } Test() { Test(0); } void print() { printf("mi...原创 2020-03-01 11:32:35 · 118 阅读 · 0 评论 -
对象的销毁
生活中的对象都是被初始化后才上市的,这是对象的构造,比如手机出厂前都会有一个默认的出厂设置供客户使用,也会在销毁前做一些清理工作,这是对象的销毁,比如手机回收一般而言,需要销毁的对象应该做清理解决方案为每个类都提供一个public的free函数对象不再需要立即调用free函数进行清理存在问题free只是一个普通的函数,必须显示的调用,很容易忘记使用对象销毁前没有做清理,很可能造成资源...原创 2020-03-01 10:26:17 · 114 阅读 · 0 评论 -
对象的构造顺序
对象的构造往往和构造函数会牵扯在一起,构造函数的函数可能会由非常复杂的逻辑所组成,不同类的构造函数的程序逻辑很可能是相互依赖的,当这种相互依赖一旦成立,那么对象的构造顺序很可能导致难以调试的Bug出现对象的构造顺序对于局部对象当程序执行流到达对象的定义语句时进行构造对于堆对象当程序执行到达new语句时创建对象使用new创建对象将自动触发构造函数的调用对于全局对象对象的构造顺序是不确...原创 2020-02-28 23:55:04 · 175 阅读 · 0 评论 -
对象的构造(上)
类是一种特殊的自定义类型,自定义类型遵守C语言中所有数据类型的操作,也可以用来定义指针,这种特殊的自定义类可以用来定义变量,从面向对象的角度就是实例化一个对象了,从程序的本质上来将就是定义一个自定义类型的变量,既然是变量它就需要占用存储空间,占用什么区域的存储空间和C语言中的说法一致,即局部变量在栈空间,全局变量在静态存储区(.bss 和 .data段)例子:#include <stdi...原创 2020-02-28 11:56:20 · 100 阅读 · 0 评论