C++

1.命名空间:类似于Java中包
标准命名空间:standard(包含很多标准的定义)
使用 using namespace std;
自定义命名空间:
namespace NSP_A{
int a = 9;
struct Teacher{
char name[20];
int age;
};
struct Student{
char name[20];
int age;
};

    }
    
    namespace NSP_B{
        int a = 12;
        //命名空间嵌套
        namespace NSP_C{
            int c = 90;     
        }
    }
2.C++的结构体可以加访问权限和C++类写法类似:
    struct MyTeacher{
        public:
        char name[20];
        int age;
        public:
        void say(){
            cout << this->age << "岁" << endl;
        }
    };
    #define PI 3.14
    //类
    class MyCircle{
    //属性(共用权限访问修饰符)
    private:
        double r;
        double s;
    public:
        void setR(double r){
            this->r = r;
        }
        //获取面积
        double getS(){
            return PI * r * r;
        }
    };
3.引用:是变量的别名,指向同一个内存空间
  主要功能:作为函数的参数或返回值
//1.单纯给变量取别名没有任何意义,作为函数参数传递,能保证参数传递过程中不产生副本
//2.引用可以直接操作变量,指针要通过取值(*p),间接操作变量,指针的可读性差
    //常引用类似于java中final
    void myprintf(const int &a){
        cout << a << endl;  
    }
  指针的引用,代替二级指针//Teacher* &p = (Teacher * *p)
    void getTeacher(Teacher* &p){
        p = (Teacher*)malloc(sizeof(Teacher));
        p->age = 20;
    }
    
    void main(){
        Teacher *t = NULL;
        getTeacher(&t);
    }
  和指针对比,更方便:
    int a = 1,b = 2;
    //指针值交换
    void swap_1(int *a, int *b){//调用  swap_1(&a,&b)
        int c = 0;
        c = *a;
        *a = *b;
        *b = c;
    }
    
    //引用值交换
    void swap_2(int &a, int &b){//调用  swap_2(a,b)
        int c = 0;
        c = a;
        a = b;
        b = c;
    }
4.C++类的一般写法:
a.新建.h文件eg,MyTeacher.h
    #pragma once    //保证这个头文件只被编译一次
    class MyTeacher{
    public:
        int age;
        char* name;
    public:
        void setAge(int age);
        int getAge();
        void setName(char* name);
        char* getName();
    };
b.新建MyTeacher.cpp
    #include "MyTeacher.h"  
    void MyTeacher::setAge(int age){
        this->age = age;
    }
    int MyTeacher::getAge(){
        return this->age;
    }
    void MyTeacher::setName(char* name){
        this->name = name;
    }
    char* MyTeacher::getName(){
        return this->name;
    }
 c.在需要用到MyTeacher类的地方引入头文件即可
5.构造函数
    class Teacher{
    private:
        char *name;
        int age;
    public:
        //无参构造函数(写了,就会覆盖默认的无参构造函数)
        Teacher(){
            cout << "无参构造函数" << endl;
        }
        //有参构造函数会覆盖默认的构造函数
        Teacher(char *name, int age){
            this->name = name;
            this->age = age;
            cout << "有参构造函数" << endl;
        }   
    };  
    void main(){
        //Teacher t1;
        Teacher t2("yuehan",20);
        //另外一种调用方式
        Teacher t3 = Teacher("jack",21);
    }
6.析构函数
    class Teacher{
    private:
        char *name;
        int age;
    public:
        //无参构造函数赋默认值
        Teacher(){
            this->name = (char*)malloc(100);
            strcpy(name,"jack walson");
            age = 20;
            cout << "无参构造函数" << endl;
        }
        //析构函数
        //当对象要被系统释放时,析构函数被调用
        //作用:善后处理
        ~Teacher(){
            cout << "析构" << endl;
            //释放内存
            free(this->name);
        }
    };
7.拷贝构造函数
    class Teacher{
    private:
        char *name;
        int age;
    public:
        Teacher(char *name, int age){
            this->name = name;
            this->age = age;
            cout << "有参构造函数" << endl;
        }
        //拷贝构造函数(值拷贝)
        //默认拷贝构造函数,就是值拷贝
        Teacher(const Teacher &obj){
            this->name = obj.name;
            this->age = obj.age;
            cout << "拷贝构造函数" << endl;
        }
        void myprint(){
            cout << name << "," << age << endl;
        }
    };
    Teacher func1(Teacher t){
        t.myprint();
        return t;
    }
    void func2(Teacher t){
        t.myprint();
    }
    void main(){
        Teacher t1("rose",20);
        //拷贝构造函数被调用的场景
        Teacher t2 = t1;//1.声明时赋值
        func2(t1);//2.作为参数传入,实参给形参赋值
        Teacher t3 = func1(t1); //3.作为函数返回值返回,给变量初始化赋值,
                                    //  注意这里会调用两次拷贝构造函数:1次是因为作为参数传入,第二次是因为作为函数返回值返回
    
        //这里不会被调用
        //Teacher t1 ;
        //Teacher t2;
        //t1 = t2;
}
8.深拷贝与浅拷贝:
  a.浅拷贝(值拷贝)问题:只会拷贝一份引用,还是指向同一个内存
    class Teacher{
    private:
        char *name;
        int age;
    public:
        Teacher(char *name, int age){
            this->name = (char*)malloc(100);
            strcpy(this->name,name);
            this->age = age;
            cout << "有参构造函数" << endl;
        }   
        ~Teacher(){
            cout << "析构" << endl;
            //释放内存
            free(this->name);
        }
        void myprint(){
            cout << name << "," << age << endl;
        }
    };  
    void func(){
        Teacher t1("rose", 20); 
        Teacher t2 = t1;
        t2.myprint();
    }       
    void main(){
        func();//在方法结束的时候,析构函数会调用两次(回收t1和t2时)
                  //因为这里是浅拷贝,所以name只分配了一块内存,进行第二次析构函数的调用时会出错!解决方法:使用深拷贝           
    }
  b.深拷贝:
    class Teacher{
    private:
        char *name;
        int age;
    public:
        Teacher(char *name, int age){
            int len = strlen(name);
            this->name = (char*)malloc(len+1);
            strcpy(this->name, name);
            this->age = age;
            cout << "有参构造函数" << endl;
        }
        ~Teacher(){
            cout << "析构" << endl;
            //释放内存
            free(this->name);
        }
        //深拷贝
        Teacher(const Teacher &obj){
            //复制name属性
            int len = strlen(obj.name);
            this->name = (char*)malloc(len+1);
            strcpy(this->name,obj.name);
            this->age = obj.age;
        }
        void myprint(){
            cout << name << "," << age << endl;
        }
    };
    
    void func(){
        Teacher t1("rose", 20);
        Teacher t2 = t1;
        t2.myprint();
    }
    
    void main(){
        func();
    }
9.构造函数的属性初始化列表
    class Teacher{
    private:
        char* name;
    public:
        Teacher(char* name){
            this->name = name;
            cout << "Teacher有参构造函数" << endl;
        }
        ~Teacher(){
            cout << "Teacher析构函数" << endl;
        }
        char* getName(){
            return this->name;
        }
    
    };
    
    class Student{
    private:
        int id;
        //属性对象
        Teacher t1;
        Teacher t2;
    public:
        Student(int id,char *t1_n, char* t2_n) : t1(t1_n), t2(t2_n){
            this->id = id;
            cout << "Student有参构造函数" << endl;
        }
        void myprint(){
            cout << id << "," << t1.getName() <<"," << t2.getName() << endl;
        }
        ~Student(){
            cout << "Student析构函数" << endl;
        }
    };
10.类的大小:
方法和静态变量都不计算到类的大小里面去
    class B{//大小为12
    public:
        int i;
        int j;
        int k;
        void myprintf(){
            cout << "打印" << endl;
        }
        static int m;
    };
11.常函数(在函数后面 加 const关键字),常函数中当前对象以及对象的成员都不能被修改
12.友元函数
    class A{
        //友元函数
        friend void modify_i(A *p, int a);
    private:
        int i;
    public:
        A(int i){
            this->i = i;
        }
        void myprint(){
            cout << i << endl;
        }
        
    };
    
    //友元函数的实现,在友元函数中可以访问私有的属性
    void modify_i(A *p, int a){
        p->i = a;
    }
13.友元类
    class A{        
        //友元类
        friend class B;
    private:
        int i;
    public:
        A(int i){
            this->i = i;
        }
        void myprint(){
            cout << i << endl;
        }   
    };
    
    class B{
    public:
        //B这个友元类可以访问A类的任何成员
        void accessAny(){
            a.i = 30;       
        }
    private:
        A a;
    };
14.运算符重载
  a.外部重载
    class Point{
    public:
        int x;
        int y;
    public:
        Point(int x = 0, int y = 0){
            this->x = x;
            this->y = y;
        }
        void myprint(){
            cout << x << "," << y << endl;
        }
    };
    
    //重载+号
    Point operator+(Point &p1, Point &p2){
        Point tmp(p1.x + p2.x, p1.y + p2.y);
        return tmp;
    }
    
    //重载-号
    Point operator-(Point &p1, Point &p2){
        Point tmp(p1.x - p2.x, p1.y - p2.y);
        return tmp;
}

  b.成员函数,运算符重载
  class Point{
    public:
        int x;
        int y;
    public:
        Point(int x = 0, int y = 0){
            this->x = x;
            this->y = y;
        }
        //成员函数,运算符重载
        Point operator+(Point &p2){
            Point tmp(this->x + p2.x, this->y + p2.y);
            return tmp;
        }
        void myprint(){
            cout << x << "," << y << endl;
        }
    };
    Point p1(10, 20);
        Point p2(20, 10);
    
        //运算符的重载,本质还是函数调用
        //p1.operator+(p2)
        Point p3 = p1 + p2;

  c.当属性私有时,通过友元函数完成运算符重载
    class Point{
        friend Point operator+(Point &p1, Point &p2);
    private:
        int x;
        int y;
    public:
        Point(int x = 0, int y = 0){
            this->x = x;
            this->y = y;
        }   
        void myprint(){
            cout << x << "," << y << endl;
        }
    };
    
    Point operator+(Point &p1, Point &p2){
        Point tmp(p1.x + p2.x, p1.y + p2.y);
        return tmp;
    }
15.父类构造函数先调用、子类的析构函数先调用
16.多重继承的二义性:多个父类有相同的属性或者函数,子类不知道该调用哪个,解决方法:虚继承(不同路径继承来的同名成员只有一份拷贝,解决不明确的问题)
    class A{
    public:
        char* name;
    };
    
    class A1 : virtual public A{
        
    };
    
    class A2 : virtual public A{
    
    };
    
    class B : public A1, public A2{
    
    };
    
    void main(){
        B b;    
        b.name = "jason";
        //指定父类显示调用
        //b.A1::name = "jason";
        //b.A2::name = "jason";
  }
17.多态(程序的扩展性)
    动态多态:程序运行过程中,觉得哪一个函数被调用(重写)
    静态多态:重载
18纯虚函数(抽象类)
    virtual void foo1();//虚函数
    virtual void foo2() = 0;//纯虚函数
    1.当一个类具有一个纯虚函数,这个类就是抽象类
    2.抽象类不能实例化对象
    3.子类继承抽象类,必须要实现纯虚函数,如果没有,子类也是抽象类
    抽象类的作用:为了继承约束,根本不知道未来的实现
19.模板函数
    template <typename T>
    void myswap(T& a, T& b){
        T tmp = 0;
        tmp = a;
        a = b;
        b = tmp;
    }
    //使用,根据实际类型,自动推导
        int a = 10, b = 20;
        myswap<int>(a,b);
        cout << a << "," << b << endl;
    
        char x = 'v', y = 'w';
        myswap(x, y);
        cout << x << "," << y << endl;
20.模板类
    //模板类
    template<class T>
    class A{
    public:
        A(T a){
            this->a = a;
        }
    protected:
        T a;
    };
    
    //普通类继承模板类
    class B : public A<int>{
    public:
        B(int a,int b) : A<int>(a){
            this->b = b;
        }
    private:
        int b;
    };
    
    //模板类继承模板类
    template <class T>
    class C : public A<T>{
    public:
        C(T c, T a) : A<T>(a){
            this->c = c;
        }
    protected:
        T c;
    };
    
    void main(){
        //实例化模板类对象
        //List<String> list;
        A<int> a(6);
        system("pause");
}
21.异常处理:
  a.
    void main(){
        try{
            int age = 300;
            if (age > 200){
                throw 9.8;
            }
        }
        catch (int a){
            cout << "int异常" << endl;
        }
        catch (char* b){
            cout << b << endl;
        }
        catch (...){
            cout << "未知异常" << endl;
        }
        system("pause");
    }
  b.throw
    void mydiv(int a, int b){
        if (b == 0){
            throw "除数为零";
        }
    }
    
    void func(){
        try{
            mydiv(8, 0);
        }
        catch (char* a){
            throw a;
        }
    }
    
    void main(){
        try{
            func();
        }
        catch (char* a){
            cout << a << endl;
        }
        system("pause");
}
  c.抛出对象异常类
        class MyException{
        
    };
    
    void mydiv(int a, int b){
        if (b == 0){
            throw MyException();
            //throw new MyException; //不要抛出异常指针     
        }
    }
    
    void main(){
        try{
            mydiv(8,0);
        }
        catch (MyException& e2){
            cout << "MyException引用" << endl;
        }
        //会产生对象的副本
        //catch (MyException e){
        //  cout << "MyException" << endl;
        //}
        catch (MyException* e1){
            cout << "MyException指针" << endl;        
            delete e1;
        }
        
        system("pause");
}
 d.throw 声明函数会抛出的异常类型
        void mydiv(int a, int b) throw (char*, int) {
            if (b == 0){
                throw "除数为零";   
            }
        }
 e.标准异常(类似于JavaNullPointerException)
    lass NullPointerException : public exception{
    public:
        NullPointerException(char* msg) : exception(msg){
    
        }
    };
    
    void mydiv(int a, int b){
        if (b > 10){
            throw out_of_range("超出范围");     
        }   
        else if (b == NULL){
            throw NullPointerException("为空");
        }
        else if (b == 0){
            throw invalid_argument("参数不合法");
        }
    }
    
    void main(){
        try{
            mydiv(8,NULL);
        }
        catch (out_of_range e1){
            cout << e1.what() << endl;
        }
        catch (NullPointerException& e2){
            cout << e2.what() << endl;
        }
        catch (...){
    
        }
    
        system("pause");
}
 f.外部类异常
    class Err{
    public:
        class MyException{
            public:MyException(){
    
            }
        };
    };
    
    void mydiv(int a, int b){
        if (b > 10){
            throw Err::MyException();
        }
        
}
22.C++类型转换
static_cast 普遍情况
const_cast 去常量
dynamic_cast 子类类型转为父类类型
reinterpret_cast 函数指针转型,不具备移植性
23.IO流
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    //IO流
    //文本文件操作
    void main(){
        char* fname = "c://dest.txt";
        //输出流
        ofstream fout(fname);
        //创建失败
        if (fout.bad()){
            return;
        }
    
        fout << "jack" << endl;
        fout << "rose" << endl;
    
        //关闭
        fout.close();
    
        //读取
        ifstream fin(fname);
        if (fin.bad()){
            return;
        }
        char ch;
        while (fin.get(ch)){
            //输出
            cout << ch;
        }
        fin.close();
}
    //二进制文件
    void main(){
        char* src = "c://src.jpg";
        char* dest = "c://dest.jpg";
    
        //输入流
        ifstream fin(src, ios::binary);
        //输出流
        ofstream fout(dest, ios::binary);
    
        if (fin.bad() || fout.bad()){
            return;
        }
    
        while (!fin.eof()){
            //读取
            char buff[1024] = {0};
            fin.read(buff,1024);
    
            //写入
            fout.write(buff,1024);
        }
    
        //关闭
        fin.close();
        fout.close();

}
24.持久化对象
    int main()
    {
        Person p1("柳岩", 22);
        Person p2("rose", 18);
        //输出流
        ofstream fout("c://c_obj.data", ios::binary);
        fout.write((char*)(&p1), sizeof(Person)); //指针能够读取到正确的数据,读取内存区的长度
        fout.write((char*)(&p2), sizeof(Person));
        fout.close();
    
        //输入流
        ifstream fin("c://c_obj.data", ios::binary);
        Person tmp;
        fin.read((char*)(&tmp), sizeof(Person));
        tmp.print();
    
        fin.read((char*)(&tmp), sizeof(Person));
        tmp.print();
    
        return 0;

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容