zoukankan      html  css  js  c++  java
  • C++概览

    目录

    一、已经有C了为什么还要有C++. 2

    二、C++基本语法... 2

    1. 数据类型、常量和变量、语句,运算符和表达式... 2

    2. new和delete. 2

    (1) 用法... 2

    三、函数... 2

    1. 函数的基本概念... 2

    2. 缺省函数... 2

    3. 内联函数... 3

    4. 重载函数、运算符重载... 3

    5. 命名空间... 5

    四、类... 5

    1.构造函数、析构函数... 5

    2.访问限定... 5

    (1)访问限定字... 5

    (2)友元... 5

    (3)句柄... 5

    3.const和static限定字... 5

    4.类的继承和包含... 5

    (1)继承的用法... 6

    (2)不同的访问限定字造成的继承差别... 6

    (3)不能被继承的对象... 6

    (4)包含... 6

    五、模板... 6

    1. 用法... 6

    六、输入输出流... 7

    1.istream对象... 7

    2.ostream对象... 7

    3.字符串流... 7

    4. 操纵符... 8

    七、异常处理... 8

    1.assert()函数... 8

    2.throw-try-catch. 8

    (1)定义异常,这个地方也可以是类... 8

    (2)抛出异常,throw 对象或对象的构造函数; 9

    (3)处理异常... 9

    八、标准模板库STL. 10

    1.顺序容器... 10

    九、附录... 11

    正文

    一、已经有C了为什么还要有C++

    C是面向过程的而C++是面向对象的语言,能够用封装、继承、多态的知识解决实际问题,有时候用C或C++都能解决同一问题,但是用 C++做C的补充可能会好些。

    二、C++基本语法

    1. 数据类型、常量和变量、语句,运算符和表达式

    这部分兼容C,另外多出一种数据类型:类类型,最典型的就是向命令行输入输出的<iostream>了。

    2. new和delete

    动态内存分配和销毁,C语言用的是malloc()和free(),主要是在动态数组的地方会用到;C++的则是使用new和delete,为指针pointer分配内存空间。一个好的习惯是new和delete成对出现;局部变量在一个作用域结束后会被销毁掉,但是new定义的指针变量的数据是放在堆内存中、程序终止后才被销毁掉

    (1) 用法

    new 类型 分配一个该类型的对象

    new 类型(初始值) 分配一个该类型的对象,并初始化

    new 类型[数组大小] 指针将得到该数组的首地址,而且数组的类型、长度已经确定

    三、函数

    析构函数不能在类里面使用,构造函数在类的外面只能使用一次

    1. 函数的基本概念

    友元函数:友元函数不是类中的成员函数。

    常函数:函数定义的最后有个const,比如int func()const,这种函数不能修改类中的成员变量(除非是mutable声明的变量)、只做简单的返回。

    函数的参数:const后面的变量不能做左值;数组、指针做参数会用到*,其他情况尽量用引用&;如果不做左值,返回类型尽量是“const 类型&”。

    有副作用:会改变当前类中成员变量,如果要返回用“*this”。

    2. 缺省函数

    C++函数的参数是可以有默认值的,而且默认值只能是从左往右依次缺。

    3. 内联函数

    对于语句操作非常少但重用性高的的函数,频繁调用会造成多余的开销,C的解决办法是宏定义、C++的解决办法是内联函数(在函数返回值的前面加上关键字inline);内联函数可以传入带自增自减的实际参数,宏定义的函数这样做可能会导致逻辑上的错误

    4. 重载函数、运算符重载

    (1)重载函数

    函数名相同,但是参数表不同的一组函数,是不是重载函数和返回类型无关;参数表不同指的是参数类型或者参数个数不一样。

    (2)运算符重载

    有两种重载方式,成员函数重载、全局函数重载,它们的参数都有一定的对应顺序。成员函数重载最多能有一个参数、全局函数重载必须有两个参数并且要定义成友元,比如输入输出重载。

    ①可以重载的运算符

    一元运算符

    ++ --

    算术运算符

    + - * / %

    关系运算符

    == != < <= > >=

    逻辑运算符

    ! && ||

    位运算符

    & | ^ ~ >> <<

    赋值运算符

    = += -= *= /= %= &= ^= |= >>= >>=

    其他

    [] () -> ->* new delete

    ②一元运算符重载的特殊情况

    //一元运算符前缀形式

    const 类型& operator++ ()

    {

    某些成员++;

    return *this;

    }

    //一元运算符后缀形式,before调用的构造函数

    const 类型 opetator++(int)

    {

    类 before(某些成员变量);

    某些成员变量++;

    return before;

    }

    //自定义类型转换

    operator 类型()

    {

    return static_cast<类型>(某些成员变量);

    }

    ③输入输出重载

    必须使用友元、全局函数重载,因为重载的参数是有顺序的,输入输出重载的左操作数是流对象、不是当前对象。

    friend istream& operator>>(istream&,type&);

    friend ostream& operator<<(istream&,const type&);

    之后在类外面定义函数,由流到对象(返回表达式)或是对象到流(返回流)

    ④重载赋值运算符

    深拷贝:完全复制一模一样的数据内容,这样读写就是自由的、因为读写自己的数据不会影响到同类对象的读写;缺点是需要内存做开销。

    浅拷贝:编译器的默认拷贝方式,简单的按成员对象依次拷贝;缺点是遇到指针、结构体等复杂对象可能会出错。

    引用计数、写拷贝:这是一种结合深拷贝和浅拷贝的拷贝方式,用指针得到想要的资源并记录引用数、当引用数为0的时候销毁资源;当引用数大于1而且需要写的时候才做深拷贝。

    OwnArray<T>& operator=(const OwnArray<T>& obj)

    {

    if(this!=&obj)

    {

    //销毁原来的数据

    ExdOwnArray();

    //更新数据,运算符重载一个特别的地方是,可以访问对方的保护甚至私有对象

    arrLen=obj.arrLen;

    arr=(T*)malloc(arrLen*sizeof(T));

    int i;

    for(i=0; i<arrLen; ++i)

    {

    arr[i]=obj.arr[i];

    }

    }

    return *this;

    }

    5. 命名空间

    为避免函数名冲突引入的一种机制。

    定义一个命名空间namespace 空间的名称{…},使用的时候是空间名称::对象,或者提前声明using namespace 空间名称;。

    四、

    类体现了封装、继承、多态的特点,定义好类后声明对象即可使用

    1.构造函数、析构函数

    2.访问限定

    (1)访问限定字

    public、protected、private,public在类中类外都可以被调用,protected和private在类中可以调用但是受保护、在类的继承中可以体现这一点。另外如果在代码中对象不声明访问限定字,那么它默认是private的。

    (2)友元

    在类的声明中有些对象前面有关键字friend,这样的对象可以访问这个类的私有数据

    (3)句柄

    3.const和static限定字

    4.类的继承和包含

    继承和包含主要目的是代码的复用

    (1)继承的用法

    class 派生类名称: [访问限定字] 基类名称, [访问限定字] 基类名称,…, [访问限定字] 基类名称

    {…初始化基类、其他类、成员对象…};

    访问限定字默认是private;基类的初始化写在派生类的初始化列表(函数名:函数或对象(传入数据),…{})中,否则基类将调用默认的构造函数;用于多重继承的基类之间如果有相同的函数名,调用的时候可能出现二义性的问题,可以通过“继承者.父类::函数”的方法来解决;同一个基类如果多次间接继承,避免二义性问题还有一种解决办法,就是虚继承(在访问限定字的前面加上virtual);析构函数的执行顺序和构造函数的调用顺序是相反的。

    (2)不同的访问限定字造成的继承差别

    基类的private对象只能是基类自己和它的友元可以访问、也就是说private对象不能被继承,所以有了protected这种类型;继承得到的变量也是可以改变它的访问权限的,比如继承得到protect的对象、可以再把它声明成private,方法是“private: 基类::对象”。

    访问限定字

    基类中的public

    基类中的protected

    public

    继承得到public

    继承得到protected

    protected

    继承得到protected

    继承得到protected

    private

    继承得到private

    继承得到private

    (3)不能被继承的对象

    构造函数、基类赋值重载函数

    (4)包含

    这是另一种代码复用的方法,做法是将其他类作为新类的数据对象,显然要实现相同的功能还是要写不必要的代码。所以相比继承,包含通用不易出错、继承常用但有时候难用。主要是多继承存在着复杂的初始化顺序,如果有些类还没有初始化就调用它,这是有问题的。一种解决的办法是用包含,另一种解决办法是所有的基类都有自己的默认构造函数,继承的时候重新初始化它们的数据即可。

    五、模板

    1. 用法

    模板的定义

    template <class T0,T1,...,Tn>

    定义和参数相关的类、函数或结构体(其中T0,T1,...,Tn是自定义的参数类型)

    模板的实例化

    类或结构体<T0,T1,...,Tn>,函数不需要这样的实例化,因为填入参数的时候就知道对应的类型了

    其中T0,T1,...,Tn是自定义的参数类型

    六、输入输出流

    需要头文件#include <fstream>;输入输出流最终都需要用close()关闭文件;对错误的输出cerr,ctrl+z中止程序运行、结束符EOF,ctrl+c结束程序运行。

    1.istream对象

    比如cin、读文件ifstream、字符串输入流istringstream

    cin.get(ch);

    接收任意字符,包括不可见字符,输入先写到ch,再到输出流

    ch=cin.get();

    EOF判断是否输入结束

    cin.get(char*,int,char delim=’ ’);

    从输入中读取一定长度的字符到字符数组中,读到delim停止读取

    cin.getline(char*,int,char delim=’ ’);

    从输入中读取一定长度的字符到字符数组中,读到delim停止读取

    getline(istream&,string&,char delim=’ ’);

    将读到的内容写到字符串,这种方式更实用些

    cin.read(char*,int);

    从输入中读取一定长度的字符到字符数组中

    cin.gcount();

    实际读取的字符数

    2.ostream对象

    比如cout、写文件ofstream、字符串输出流ostringstream

    cout.put(ch);

    打印任意字符,包括不可见字符

    cout.write(char*,int);

    写一定长度的字符串

    ofstream obj(“文件名”,模式);

    初始化一个ofstream对象并打开文件,模式可以是ios::in只读、ios::out只写、ios:app追加,模式视情况可以省略

    ofstream obj; obj.open(“文件名”,模式);

    初始化一个ofstream对象并打开文件

    3.字符串流

    需要头文件#include <sstream>,字符串流可以起到一种桥的作用(类型转换,如果stringstream需要循环使用一定要先clear()),写到字符串流再从字符串流中读出;其中.str();将字符串流转换为字符串string,.str(const string&);在字符串流中写入新的字符串内容;string对象.c_str()可以得到char*,char*转换成string是直接赋值。

    //这是一个类型转换的示例,其他类型转换成string,string转换成char*就可以进一步变为其他类型

    int a=1;

    float b=3.14;

    double c=8.848;

    string str="I am str ";

    stringstream format;

    format<<a<<" "<<b<<" "<<c<<" "<<str<<endl;

    printf("%s",format.str().c_str());

    4. 操纵符

    一般写在要操作对象的前面

    showbaseboolalpha

    布尔值文字输出

    showbase

    显示进制的前缀

    showpoint

    总是显示小数点

    showpos

    正数显示+

    uppercase

    十六进制0X、科学计数法显示E

    *dec或者dec

    十进制显示

    hex

    十六进制显示

    oct

    八进制显示

    endl

    换行

    七、异常处理

    exit()可以终止程序的运行,但是已经构造的静态对象的析构函数会被调用;abort()也可以终止程序的运行,已经构造的静态对象的析构函数不会被调用;抛出异常会调用terminate(),它的默认行为是调用abort()

    1.assert()函数

    将正常情况的条件语句写到assert()中,这样条件异常的时候会终止程序的运行并报告错误

    2.throw-try-catch

    这种方式和上面不同的地方在于发现异常、程序结束前可以自定义一些操作;try{}catch(…){}将捕获所有异常

    (1)定义异常,这个地方也可以是类

    //定义异常,这是个枚举对象

    enum EHstate

    {

    noError,

    zeroOp,

    negativeOp,

    severeError

    };

    enum EHstate st=noError;

    (2)抛出异常,throw 对象或对象的构造函数;

    //抛出异常

    int mathFunc(int iv) throw(EHstate)

    {

    if(iv==0)

    {

    st=zeroOp;

    throw st;

    }

    printf("iv: %d ",iv);

    return iv;

    }

    (3)处理异常

    //处理异常,修改异常后再抛出(有些异常操作不能一次就完成)

    void calculate(int op) throw(EHstate)

    {

    try

    {

    mathFunc(op);

    }

    // //拷贝出来的局部变量e

    // catch(EHstate e)

    // {

    // printf("EHstate异常:%d ",e);

    // }

    //被抛出的异常对象的引用

    catch(EHstate& e)

    {

    printf("EHstate异常:%d ",e);

    e=severeError;

    //因为修改了引用也就修改了原来的异常对象

    throw;

    }

    }

    八、标准模板库STL

    1.顺序容器

    容器

    头文件

    说明

    vector

    #include <vector>

    动态数组

    list

    #include <list>

    列表

    deque

    #include <deque>

    双端队列

    stack

    #include <stack>

    queue

    #include <queue>

    队列

    priority_queue

    #include <queue>

    优先队列

    九、附录

  • 相关阅读:
    Idea的类中使用实体类(有@Data注解)的Get/Set方法报错
    Springboot前后端分离中,后端拦截器拦截后,前端没有对应的返回码可以判断
    Window NodeJs安装
    Linux(CENTOS7) NodeJs安装
    Linux(CENTOS7) YUM方式安装mysql5.7
    根据M3U8地址下载视频
    Mysql时间范围分区(RANGE COLUMNS方式)
    Window Mysql5.7免安装版配置
    Window Jdk配置(win7/win10都可以)
    .net core2.0 读取appsettings.json
  • 原文地址:https://www.cnblogs.com/guomc/p/11179382.html
Copyright © 2011-2022 走看看