C++基础知识

3 篇文章 0 订阅
C++新增了引用类型,支持更严格的类型检查,引入了面向对象特性如类、继承和多态。此外,它还支持泛型编程(模板)、异常处理、函数重载以及命名空间。C++的编译过程包括预处理、编译、汇编和链接。C与C++的区别在于const的处理、引用类型、内联函数等。C++通过new和delete操作符管理动态内存,并提供了标准流进行输入输出。STL(标准模板库)是C++的重要组成部分,包含容器、算法和迭代器等。
摘要由CSDN通过智能技术生成

C++新增特性

更为严格的类型检查  
新增变量引用
	引用:给变量取别名,是一种数据类型
	函数传参:值传参,地址传参,引用传参
	int a = 123;
	int &b = a;//给变量a取别名b
支持面向对象
	类、对象、继承、多态、虚函数及RTTI(运行时类型识别)
新增泛型编程
	目的:编写与类型无关的代码
	模板:函数模板、类模板(STL标准模板库)
支持异常处理
支持函数及运算符重载
	函数重载:在同一个作用域下可以定义多个同名且参数不同函数
支持命名空间
	管理函数名、变量名、类
	::作用域访问符
	
	namespace name
	{
		//函数
		//变量
		//类
	}
	int main()
	{
		name::函数;	
	}
	//or
	using namespace name;

编译c++程序

编译过程:
	预处理 .c->.i
	编译 .i->.s
	汇编 .s->.o
	链接 .o->elf
编译器:
	g++ 可执行文件

c与c++的兼容和差异

const:只能初始化,不能修改值
强制类型转换
	(强转类型)表达式; //c
	强转类型(表达式);//c++ 
引用类型
内联函数
	inline 存储类型 数据类型 函数名 (参数列表)//节省运行时间,不能有复杂的控制语句
函数重载
函数模板
函数的默认参数
	int add(int a=0,int b=0);

结构体

struct 结构体名
{
	//成员变量
	//成员函数
};
结构体名::成员变量//在结构体外定义结构体变量

权限

private://变为私有对象
protected://变为受保护对象
public://变为公共对象

内存模型

作用域
	局部域
		局部变量的作用域
	全局域
		全局变量的作用域
	名字空间域
		定义在命名空间的
	类域
		在类中的
链接性:描述了名称如何在各个单元中的共享
	外部链接:名称可以在文件间共享
	内部链接:名称仅在此文件中共享

动态内存

new/delete运算符
new:申请空间
delete:释放堆区空间

char *q = new char [20];
delete [] q;
int *p = new int;
delete p;

标准流,输入输出

using namespace std;
cin
cout

类和对象

opp的三大特征
	封装:代码模块化
	继承:代码重用
	多态:接口重用
类
	是一种自定义类型
	是对一类事物共有属性和方法的抽象
	是数据类型
	不占用空间
类的定义
	class 类名
	{
		//成员变量
		//成员方法
	}

对象
	类名 对象名; //Stu stu01;
	类名 *对象名 = new 类名; //Stu *stu02 = new Stu;

构造和析构顺序
	由对象的生命周期决定
	同生命周期,先构造的后析构,后构造的先析构

拷贝构造
	用一个对象去初始化另一个对象的构造函数

static关键字

C:
修饰局部变量:修改局部变量的生命周期
修饰全局变量:修改全局变量的作用域
修饰函数:修改函数的作用域,只能在本文件调用	

C++:
static修饰成员变量
	不受对象的影响
	不会在类初始化时初始化
	在类的外部初始化
	类的共享成员
	不可使用this指针
static修饰成员函数

const关键字

C:
修饰变量:变量是只读变量,只能初始化,不能修改
修饰指针:

C++:
const成员变量:只能初始化,不能被修改(在类中使用构造方法的初始化列表进行初始化)//构造函数(参数) : const成员名(参数){}
const成员函数:不能通过const函数修改类对象
const对象:不能修改类对象

友员(类的朋友)(可以对类的私有成员直接访问)

友员函数:在类中对函数使用friend进行修饰,成为友元函数。
	friend void setval(Demo &obj,int val);
	void setval(Demo &obj,int val)
	{
			obj.val = val;
	}
友元成员函数:一个类的成员函数是另一个类的友元函数
友元类:friend class 类名;//类B可以自由访问A的私有成员

不能继承,无交换性,无传递性

运算符重载

概念:给已有的运算符指定新的功能
目的:c++预定义的运算符只能对基本类型进行操作,想要让对象能够向基本类型操作,则需要运算符重载
语法:
	返回值类型 operator 运算符 (参数)
	{
		函数体;
	}
	. ?: sizeof :: * 无法重载
	
	->(特殊):重载返回该类型的指针,使用时实际上是p->m=10; // (p.operator->())->m = 10
	[链接](http://www.tutorialspoint.com/cplusplus/class_member_access_operator_overloading.htm)

友元运算符重载

概念:运算符重载作为类的友元
class 类名
{
	friend 返回值类型 operator 运算符 (参数);
}

成员运算符重载

概念:运算符重载作为类的成员
class 类名
{
	返回值类型 operator 运算符 (参数);
}
返回值类型 类名::operator 运算符 (参数)
{
	函数体;
}

输出流运算符重载

ostream &operator <<(ostream &os,const Demo &a)
{
	os<<a.val;
	return os; 
}

函数模板

泛型编程
	模板是泛型编程的基础
	致力于编写与类型无关的代码
语法
	template <class 参数名, class 参数名, ......>//类型形参列表
	返回值类型 函数名(形参列表)
	{
		函数体
	}

	class/typename:指定参数类型

	eg:
	template <class T>
	T add(T &a,T &b)
	{
		return a+b;
	}
	int main()
	{
		int a=10;
		int b=20;
		cout<<add(a,b)<<endl;
	}
	
函数重载与函数模板
函数重载:功能相近且参数不同时选择函数重载
函数模板:功能相同且参数类型不同时选择函数模板

类模板

语法
	template<class 形参名, ......>
	class 类名
	{
		//成员
	}

	eg:
	template <class T>
	class Demo
	{
		private:
			T val;
		public:
			Demo(T val) : val(val)
			{
			}
			~Demo()
			{
			}
			Demo<T>::setval(T val);
	};

	template<class T>//每次定义外部函数都需定义
	void Demo<T>::setval(T val)
	{
		this->val = val;
	}

	int main()
	{
		Demo<int>(123);
	}

模板默认参数

eg:
template <class T=int>//只可在类前默认

非类型模板参数

模板参数列表中可以定义确定类型的变量
eg:
template <class T,int len>//T类型实参,len非类型模板参数(只能为int,*,&)

类继承(代码复用)

概念
	用已有的类来建立专用类的技术
	已有的类叫父类
	专用的类叫子类
语法
	class 子类名 : 权限访问限定符 父类名1, 权限访问限定符 父类名2
	{
	}
	权限访问限定符:public,private,protected
	
				基类                 派生类
	
public继承:     	public               public
				protected            protected
				private              只能通过基类的接口访问
				
protected继承:  public               protected
				protected            protected
				private              只能通过基类的接口访问
				
private继承:    public               private
				protected            private
				private              只能通过基类的接口访问
				
eg:	
	class Base
	{
		private:
			int val;
		public:
			Base(int val=0) : val(val)
			{}
			~Base()
			{}
			void setval(int val)
			{
				this->val = val;
			}
			int getval()
			{
				return val;
			}
	};
	class Inherit : public Base
	{
		private:
			int newval;
		public:
			Inherit()
			{}
			~Inherit()
			{}
	};
	class Inherit : public Base
	{
		private:
			int newval;
		public:
			Inherit(val) : Base(val)//给父类的构造函数传参
			{}
			~Inherit()
			{}
	};

关系

is-a关系(继承关系)
has-a关系(组合关系)
is-implemented-a关系(实现一个类用到了另一个类)
is-like-a关系(多重继承)

多重继承

一个类有多个父类
eg:
class Man{};
class Wolf{};
class Wolfman : public Man,public Wolf
{};
可能引发二义性(父类都继承一个类,调用父类的方法可能会冲突)(使用虚基类和作用域解决)

多态(接口复用)

概念:
一个接口,由于个体差异有多种实现方法

虚函数
用virtual修饰成员函数,就是虚函数
eg:
class Demo
{
	public:
		vitrual void prt()
		{}
};

限制:
非成员函数不能为虚函数
静态成员函数不能为虚函数
构造函数不能定义为虚函数,析构函数可以为虚函数
声明时用virtual修饰,定义时不需要修饰
基类的成员函数成为虚函数后,其派生类同名函数均为虚函数

eg:
class Base
{
	public:
		Base()
		{}
		~Base()
		{}
		void prt()
		{}
};
class Inherit : public Base
{
	public:
		Inherit()
		{}
		~Inherit()
		{}
		void prt()
		{}
};
void prtmsg(Base &obj)
{
   	obj.prt();//静态链接,在编译时由类型决定的函数,由于其形参为Base,故调用Base的prt
}
int main()
{
   	Base b;
  	Inherit i;
 	prtmsg(b);
	prtmsg(i);
}
在定义基类成员函数时,使用virtual进行修饰则可以实现调用Inherit的prt(成为动态链接)
virtual void prt()
{}

重载:是在一个类中多态性的一种表现,是指在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型。
覆盖(重写):是指派生类函数覆盖基类函数。覆盖一个方法并对其重写,以达到不同的作用。重写的基类中被重写的函数必须有virtual修饰。
隐藏:是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。

动态联编

联编(链接)
	就是将模块或者函数合并在一起生成可执行代码的处理过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。
静态联编(静态链接)
	是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定。
动态联编(动态链接)
	是指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定。C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚拟函数就必须要使用动态联编了。

虚函数表的技术(实现多态)

基类的虚函数表登记的基类的虚函数,子类的虚函数表登记的是子类的虚函数;
定义对象时会给虚函数表的地址分配空间,即对象的指针指向的是虚函数表的首地址

虚继承

解决多重继承引发的二义性
class A : public virtual Base{};
class B : public virtual Base{};
class C : publc A, public B{};

虚析构

当基类析构函数为虚时,子类析构自动为虚
当子类对象结束时,会自动析构基类对象
Base *p = new Inherit;
delete p;

抽象类

纯虚函数
	virtual 返回值类型 函数名 (参数列表)=0;//只声明不定义
限制
	含有纯虚函数的类叫抽象类
	只能是派生类的基类,不能有实例
	不能有static成员
	基类的纯虚接口需要在派生类中实现

限制构造函数(主要用于抽象类)

概念:构造函数的权限为protected/private
目的:限制构造对象

异常

概念:不正常,发送错误信息,处理异常(设计者检查错误并返回,使用者处理错误)

异常处理机制:try(检查)->throw(抛出)->catch(捕获)

异常处理格式
	try
	{
		//检查语句
		if(错误1)
		{
			throw 异常1;		
		}
		else if(错误2)
		{
			throw 异常2;	
		}
		...
	}
	catch(异常1)
	{
		处理异常1		
	}
	catch(异常2)
	{
		处理异常2
	}
	...

标准异常(https://cplusplus.com/reference/stdexcept/)
	exception(基类)
	logic_error(逻辑错误)	runtime_error(运行时出错)
	...			...
	
eg:
int div(int a,int b)
{	
	if(b==0)//检错
	{
		throw invalid_argument("invalid argument");//抛出异常
	}
	else
	{
		return a/b;
	}
}
int main()
{
	int a = 1;
	int b = 0;
	try
	{
		cout << div() << endl;
	}
	catch(invalid_argument &iserr)//捕获异常
	{
		cout << iserr.what() <<endl;//处理	
	}
}

自定义异常
	由已有的异常类派生
		class 异常类 : public exception
		{};

		eg:
		class Myexception : public exception
		{
			public:
				Myexception(const char* what_arg) noexcept : what_arg(what_arg)
				{}
				~Myexception() noexcept
				{}
				const char* what() noexcept
				{
					return this->what_arg;
				}
			private: 
				const char *what_arg; 	
		};
	自定义
		eg:
		class Myexception
		{
			public:
				Myexception(const char* what_arg) noexcept : what_arg(what_arg)
				{}
				~Myexception() noexcept
				{}
				 const char *what() noexcept
    					{
        						return this->what_arg;
    					}
			private: 
				const char *what_arg; 	
		};

转换函数

目的:解决类型转换(自定义类型转换为基本类型)

转换函数
	语法
	operator 新类型名() const
	{
		实现转换的语句
	}

标准转换函数
eg:
	int *p = NULL;
		char *q = NULL;
		p = reinterpret_cast<int *>(q);//转换指针类型


		const char *a = NULL;
		char *b = NULL;
		b = const_cast<char *>(a);//将const指针转换为普通指针


		Base *base;
		Inherit *iherit;
		iherit = static_cast<Inherit*>(base);//将基类转换为派生类

		Base01 *base01;
		Inherit01 *inherit01;
		inherit01 = dynamic_cast<Inherit01*>(base01);//将基类转换为派生类(有虚函数>

explicit关键字(阻止隐式类型转换)
	eg:
	class Demo
	{
			private:
    				int val;
			public:
    				explicit Demo(int val=0):val(val)//防止隐式类型转换
    				{}
    				~Demo()
    				{}
    				int const getval()
    				{
        					return this->val;
    				}
	};

	int main()
	{
			Demo obj;
		obj = Demo(123);//强制转换 
		obj = (Demo)123;
			obj = 123;//隐式转换,系统默认匹配构造函数参数(无效)
			cout << obj.getval() << endl;
	}

自定义转换函数
	eg:
	class Demo
	{
		private:
    				int val;
			public:
    				Demo(int val = 10) : val(val)
    				{}
    				~Demo()
    				{}
    				operator int()
   				{
        					return this->val;
    				}
	};

智能指针

目的:只关心申请资源,不关心释放资源

本质:重载指针运算符(* ->)

shared_ptr:共享指针(多个指针指向同一片空间)
	引入计数器:构造对象,计数器+1,析构对象,计数器-1		
	eg:
	class Demo
	{
		private:
			int val;
		public:
			void setval(int val)
			{
				this->val = val;
			}
			int getval()
			{
				return this->val;
			}
	};
	int main()
	{
		shared_ptr<Demo>p(new Demo);
		shared_ptr<Demo>q(p);
		
		p->setval(666);
		q->setval(888);
	}

unique_ptr:独享指针
	任意时刻只能有一个指针指向对象
	eg:
	unique_ptr<Demo>up(new Demo);
		up->setval(999);

weak_prt:弱指针
	配合共享指针判断对象是否存在
	eg:
	shared_ptr<Demo> p(new Demo);
	weak_ptr<Demo> q = p;

	p.reset();//Demo对象被析构
	if(q.expired())//判断Demo对象是否存在,true为不存在,false为存在
	{
		cout << "Demo is not exist" << endl;
	}

STL(标准模板库)(standard template library)

容器:特殊的数据结构,实现了数组、链表、队列等等,实质是模板类
算法:排序、遍历、查找等等,实质是模板函数
迭代器:一种复杂的指针,可以通过其读写容器中的对象,实质是运算符重载
空间配置器:容器的空间配置管理的模板类
配接器:用来修饰容器、仿函数、迭代器接口
仿函数:在类中重载 (),让对象模仿函数,调用实现功能

STL序列容器:vector、deque、list【https://www.jianshu.com/p/9ce095efeace】   STL常用接口实例:https://blog.csdn.net/zb1593496558/article/details/80987071
vector:相当于一个数组
list:相当于一个双向链表
deque:相当于双端队列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值