一、内存模型与命名空间
内存模型:解决如何取分别相同数据
命名空间:解决C++程序中标识符重名的问题
//--函数:namespace
namespace Test
{
//代码块
}
/*访问格式1
Test ::a;
访问格式2:
关键字:
using test::a;
注:
(1)命名空间是可以发生嵌套
(2)命名空间可以分为有名的命名空间和无名的命名空间(实际开发中有名的名空间用的比较多)
(3)命名空间是属于全局的一部分,只不过是取了全局的一块区域命了一个名称而已
(4)访问命名空间的时候需要用到域作用符号
二、类和对象
类:包含某些特征和行为的集合
class 类名(标识符名称)
{
//特征---变量
//行为---函数
};
对象:类的实例化
//栈区和堆区实例化格式
类名 * 对象名(标识符名称);
类名 * 对象名(标识符名称)= new 类名;
例题:
#include"iostream"
using namespace std;
//创建类 名为Test
class Tast
{
public:
//类的特征--变量
int sum,a,b;
//类的行为函数
void lnit(int c, int d)
{
a = c;
b = d;
sum = c - d;
}
void print()
{
cout << a << "-" << b <<"="<< sum << endl;
}
};
int main()
{
Tast a, b;
a.lnit(68, 55);
b.lnit(18, 36);
a.print();
b.print();
return 0;
}
访问修饰符的作用范围
(1)public(公共) 所有可见
(2)private(私有) 只有自己这个类下private和友元函数可见
(3)protected(受保护) 只有类的外部不可见
注:
a、如果在类里面没有写任何的类的成员访问修饰符,那么该类下的成员都是归于private属性下。
b、一般将成员变量放置到private属性下
三、标准输入输出流
标准输入:用其他输入设备进行数据写入内存的操作,称输入流
cin>>变量1>>变量2>>变量3..............................;
标准输出:从内存取出数据并输出到显示器上
cout<<数据1<<数据2<<数据2..............................;
clog:console log // clog:标准的日志的输出
使用方式:跟cout一样
cerr:标准的错误输出流
从内存里获取错误的数据(程序在运行的时候,产生的错误)输出到控制台
cerr:console error
使用方式:跟cout一样
注:为了防止数据产生冲突,编译器在内存分别为输入输出开辟了一个缓冲区,该缓冲区用于存放数据
四、运算符重载
1、重载、重写、隐藏(覆盖)
重载:相当于同种函数可以多次使用
使用条件:函数参数不能完全一样||返回值不一样||顺序不一样满足其中一个就可以发生重载
例如:
void function()
{
//代码块
}
void function(int a,char b)
{
//代码块
}
void function(char b,int a)
{
//代码块
}
int function()
{
//代码块
}
重写:就是将原来函数重新复制一份(函数的返回值、函数名、参数个数、类型、顺序都相同)
隐藏:就是将原来函数(变量)重新复制一份,就将原来的函数(变量)覆盖(隐藏),隐藏一般用的最多的是具有继承关系的两个类中
五、继承与多态
1.继承
单继承:
一个类的对象共享了另一个类的成员变量和成员方法
多继承:
一个类的对象共享了其他多个类的成员变量和成员方法
//基类(父类)
class Father
{
//代码块
}
//基类(父类1)
class Father1
{
//代码块
}
//派生类(子类) 单继承
//权限三种 public private protected
class Son:public Father
{
//代码块
}
//派生类(子类) 多继承
class Son:public Father,private Father1
{
//代码块
}
2.多态
构成多态性:
(1)两个类具有继承关系
(2)子类中必须重写父类的方法(子类方法中的内容与父类中的方法可以不一样)
(3)父类中的方法必须是虚函数
虚函数:
虚函数相当于是一个普通的成员函数,只不过在该函数前加了一个关键字“virtual”,那就表明该函数是一个虚函数
声明格式:
virtual 返回值类型 函数名 (参数列表);
定义格式:
virtual 返回值类型 函数名 (参数列表)
{
//函数体
}
纯虚函数:再虚函数基础上加上一个=0就是纯虚函数
注意:
a、抽象类只是给子类提供一个基类
b、抽象类不能实例化为对象
c、抽象类里只是描述了一些行为,但没有具体实现行为(纯虚函数),需要在子类中去重新实现抽象类的行为
六、异常
C++中一种容错机制,是一个错误处理系统。
异常处理:
C++提供了三个关键字:throw 、try、catch
throw :抛出异常信号
try:执行程序中,若有问题它能检查出来
catch:捕获异常信号,若为catch(...)则是所有异常信号接收(前提是前面的异常信号没被捕获)
#include"iostream"
using namespace std;
class auto_u
{
public:
int sum = 0;
int run(int i, int j)
{
if(j==0)
{
throw 0;
}
else
{
throw 'o';
return i / j;
}
}
};
int main()
{
auto_u auto_u;
try
{
auto_u.run(3,1);
}
catch(int)
{
cout << "捕捉到错误int类型" << endl;
}
catch (...)
{
cout << "捕捉到错误未知类型" << endl;
}
}
自定义异常:
1.需要继承C++提供的所有异常的基类exception,可以在自定义的异常类重写what()方法,用于查看产生的异常的类型
例题:
#include"iostream"
using namespace std;
//自定义异常类需要exception这个基类的基础
class MyExecption :public exception
{
public:
const char* str;
MyExecption(const char* obj)
{
str = obj;
}
const char* what()
{
return str;
}
};
char function(int a,int b)
{
if (b == 0)
{
throw out_of_range("输入的数据分母不能为零");//标准的异常
//return MyExecption("分母不能为零");
}
else
{
return a / b;
}
}
int main()
{
try
{
function(10, 0);
}
catch (out_of_range& h)
{
cout << "产生的异常:" << h.what() << endl;
}
catch(MyExecption&h)
{
cout << "产生的异常" << h.what() << endl;
}
catch (...)
{
cout << "捕捉到未知错误" << endl;
}
}
七、模板
关键字:template
注:class 与typename标识符等价
//模板格式
template <模板形参1,模板形参2,.......> 函数的返回值 函数名(函数形参列表)
{
//函数体
}
例:
template <class T1>class Test
{
public:
T1 a;
Test(T1 b)
{
a = b;
cout << "a=" << a << endl;
}
八、智能指针
将裸指针开辟的堆空间的管理权交给智能指针管理。
1.shared_ptr智能指针
特点:
1.每个 shared_ptr 对象在内部指向两个内存位置:
(1)指向对象的指针。
(2)用于控制引用计数数据的指针。
2.共享所有权如何在参考计数的帮助下工作:
有新的shared_ptr指向这个对象时,引用计数数据的指针就+1;反之-1,当引用计数数据的值=0时,智能指针将该空间释放。
指针分类:
强指针 shared_ptr<Father>father;
弱指针 weak_ptr<Son>son;
唯一指针 unique_ptr....
例子如下:
#include"iostream"
using namespace std;
class Son;
class Father
{
public:
~Father()
{
cout << "Father释放资源" << endl;
}
//共享指针劣势:循环引用会导致资源不会释放
//shared_ptr<Son>son;//强指针
weak_ptr<Son>son;
};
class Son
{
public:
~Son()
{
cout << "Father释放资源" << endl;
}
shared_ptr<Father>father;
};
int main()
{
Father* father = new Father();
Son* son = new Son();
//管理父类堆空间
shared_ptr<Father>father1(father);
//管理子类堆空间
shared_ptr<Son>son1(son);
father->son = son1;
son->father = father1;
cout << "共享指针个数: " << father1.use_count() << endl;
cout << "共享指针个数: " << son1.use_count() << endl;
}