美文网首页c/c++
c++基础语法

c++基础语法

作者: 曾大稳丶 | 来源:发表于2018-07-27 13:51 被阅读0次

    c和c++联系

    1. c++代码可以混编c代码,既可以写c也可以调用c
    2. c++面向对象,c面向过程
    3. 开源框架大部分都是基于c++写的

    打印

    #include "stdio.h"
    #include <iostream>
    
    using namespace std;
    
    void main() {
        //打印
        //cout << "hello world " << endl;//换行
        cout << "hello world " ;//不换行
    }
    
    

    常量

    void main() {
        //常量
        const int number = 0;
        //在c文件,这里可以通过指针修改值,但是在c++中不能通过地址修改值,一般编译器编译不能通过,但是某一些编译器可以,但是也不能修改值
        //int *number_p = &number;
        //*number_p = 20;
    
        getchar();
     }
    
    

    引用

    #include "stdio.h"
    #include <iostream>
    
    using namespace std;
    
    //通过指针来变换
    void swap(int *num1,int* num2) {
        int temp = 0;
        temp = *num1;
        *num1 = *num2;
        *num2 = temp;
    }
    
    //通过引用来变换
    void swap(int &num1, int& num2) {
        cout << "number1p = " << &num1 << "  number2p = " << &num2 << endl;//number1p = 00BBFA08  number2p = 00BBF9FC
        int temp = 0;
        temp = num1;
        num1 =num2;
        num2 = temp;
    }
    
    void main() {
        //引用:四驱模型值的拷贝,引用其实是地址赋值,可以看成同一块内存的另外一个变量
        
        //交换值
        int number1 = 10;
        int number2 = 20;
        //通过指针
        //swap(&number1,&number2);
        //通过引用
        cout << " number1p = " << &number1 << "  number2p = " << &number2 <<endl; // number1p = 00BBFA08  number2p = 00BBF9FC
        swap(number1,number2);
    
        cout << "number1 = " << number1 << "  number2 = " << number2 << endl;// number1 = 20  number2 = 10
    
    
        //加深理解
        int a = 10;
        int b = a; //赋值  b 和 a分别指向不同的内存
        cout << "ap = " << &a << "  bp = " << &b << endl;// ap = 010FF730  bp = 010FF724
    
        int& c = a;//引用  a和c都指向一块地址
        cout << "ap = " << &a << "  cp = " << &c << endl;// ap = 010FF730  cp = 010FF730
        c = 20;
        cout << "a = " << a << "  c = " << c << endl;//a = 20  c = 20
    
        getchar();
     }
    
    

    常量引用

    #include "stdio.h"
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    typedef struct 
    {
        char  name[20];
        int age;
    } Student;
    
    //常量引用 const Student & stu只能读,不能修改
    void insertStudent(/* const */ Student & stu) {
        //stu.name = "李四";  //不能修改
        strcpy_s(stu.name, "李四");  //这样的话就修改了值,如果不想修改stu,就在参数加上const 变为只读
    }
    
    void main() {
        Student stu = {"张三" ,45};
        insertStudent(stu);
        cout << "stu.name = " << stu.name << " stu.age = " << stu.age << endl;
        getchar();
     } 
    
    

    重载 :c不支持重载 ,c++支持

    #include "stdio.h"
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    //重载
    //int add(int number1, int number2) {
    //
    //  return number1 + number2;
    //}
    
    int add(int number1, int number2,bool cache = false) {
    
        cout << cache << endl;
    
        return number1 + number2;
    }
    int add(int number1, int number2,int number3) {
    
        return number1 + number2 + number3;
    }
    
    
    void main() {
        int number1 = 10;
        int number2 = 20;
        int number3 = 30;
        int sum1 = add(number1, number2);
        int sum2 = add(number1, number2 , number3);
    
        printf("%d , %d", sum1, sum2);
    
        getchar();
     } 
    

    JAVA里的Class

    #include "stdio.h"
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    class Student{
    private: // 私有 包装,影响下面所有的属性或者方法
        char * name;
        int age;
    
    public://影响下面所有的方法或者属性
        
        void setAge(int age){
            this->age = age;
        }
        void setName(char*name) {
            this->name = name;
        }
    
        int getAge() {
            return this->age;
        }
    
        char * getName() {
            return this->name;
        }
    };
    
    
    void main() {
        Student stu;
        stu.setAge(25);
        cout << stu.getAge() << endl;
    
        Student *student = new Student();
    
        student->setAge(24);
        
        cout << student->getAge() << endl;
    
        getchar();
     } 
    
    

    注意:在开发过程中,cpp或者c会被编译为dll或者so供其调用者使用,一般把public的函数定义到h文件,不然调用者都不知道有哪些函数。

    构造函数

    class Student{
    
    public:
        //1.
        Student() {};
    
        //2. 
        Student(char * name):age(0) { // 相当于thix->age = 0
            this->name = name;
        };
    
        //3.
        //构造函数相互调用 先调用两个参数的,在调用一个参数的
        Student(char*name) :Student(name,0) { // 相当于thix->age = 0
        };
    
        //4.
        Student(char*name,int age) {
            this->name = name;
            this->age = age;
        };
    
    private:
        char * name;
        int age;
    
    public:
        
        void setAge(int age){
            this->age = age;
        }
        void setName(char*name) {
            this->name = name;
        }
    
        int getAge() {
            return this->age;
        }
    
        char * getName() {
            return this->name;
        }
    };
    
    

    析构函数

    
    class Student{
    
    public:
        Student() {};
    
        Student(char*name,int age) {
            this->name = (char*)malloc(sizeof(char)*100);
            strcpy(this->name,name);
            this->age = age;
        };
    
        //析构函数:对象被回收的时候会被调用,只能有一个,不能有参数
        ~Student()  {
            //释放内存  这里name使用malloc举个例子
            free(this->name);
        }
    
    
    private:
        char * name;
        int age;
    
    public:
        
        void setAge(int age){
            this->age = age;
        }
        void setName(char*name) {
            this->name = name;
        }
    
        int getAge() {
            return this->age;
        }
    
        char * getName() {
            return this->name;
        }
    };
    
    

    malloc free new delete区别

    1. malloc/free一起用 new/delete一起用
    2. malloc/free不会调用构造函数和析构函数,new/delete会调用构造函数和析构函数
    3. 如果用了new,一定要记得delete释放内存

    拷贝构造函数

    Class(const Class& C)  
        {  
            //..赋值
        }  
      
    

    https://blog.csdn.net/lwbeyond/article/details/6202256

    可变参数 java的Object...

    
    #include "stdio.h"
    #include <stdarg.h>
    #include <iostream>
    using namespace std;
    
    //可变参数
    int sum(int count,...) {
        va_list vp;
        //可变参数指定开始  count代表从哪里开始
         va_start(vp,count);
         int sum = 0;
         for (int i = 0; i < count; i++) {
             sum += va_arg(vp, int);
         }
         va_end(vp);
         return sum;
    }
    
    int main()
    {
    
        cout<<sum(3, 2, 3, 4)<<endl;
        getchar();
        return 0;
    }
    

    static

    #include "stdio.h"
    #include <stdarg.h>
    #include <iostream>
    using namespace std;
    
    class Student
    {
    public:
        char * name;
        int age;
        static int tag;
    
    
        Student() {
            tag = 10;
        }
    
        static void change() {
            tag += 20;
        }
    
         void change2() {
            tag += 20;
        }
    
    };
    
    
    //静态属性 在c++中必须初始化,初始化必须这么写
    int Student::tag =15;
    
    int main()
    {
        cout << Student::tag << endl;//15
    
        Student stu;
        cout << Student::tag << endl;//10
    
        Student::change(); //静态函数调用静态变量
        cout << Student::tag << endl;//30
    
        stu.change2(); //非静态函数调用静态变量
        cout << Student::tag << endl;//50
    
        getchar();
        return 0;
    }
    // 1. 调用使用 双冒号 ::
    // 2. 静态属性 必须初始化
    // 2. 静态函数只能操作静态的相关函数和属性
    

    const函数

    
    #include "stdio.h"
    #include <stdarg.h>
    #include <iostream>
    using namespace std;
    
    class C
    {
    public:
        int age;
    public:
        const void change() {
            this->age += 12;
        }
    
        //const 在()之后主要用来限制this关键字
        void change2() const {
            //this->age += 12; //不能对类的属性进行修改
        }
    
        C(int age) {
            this->age = age;
        }
    
    };
    
    
    int main()
    {
        C *c = new C(15);
        c->change();
        cout << c->age << endl;
    
        
        getchar();
        return 0;
    }
    

    友元函数

    #include "stdio.h"
    #include <stdarg.h>
    #include <iostream>
    using namespace std;
    
    class Person
    {
    public:
        Person(int age) {
            this->age = age;
        };
        
        int getAge() {
            return this->age;
        }
        //友元函数 申明之后,friend_change就可以调用私有属性
        friend void friend_change(Person * person, int age);
    
    
    private:
        int age = 0;
    
    
    };
    
    void friend_change(Person * person, int age) {
        //age private修饰,在类的内部才能访问私有函数。如果非要访问,就得用到友元函数
        //如果该方法设置为友元函数,那么在外部可以访问其私有属性
        person->age = age;
    }
    
    
    
    
    
    int main()
    {
        Person person = Person(24);
        friend_change(&person,20);
        cout << person.getAge() << endl;//20
        getchar();
        return 0;
    }
    

    构造函数,析构函数,拷贝构造函数,普通函数,静态函数,友元函数实现

    Student.h

    #include "stdafx.h"
    
    class Student
    {
    private:
        int age;
        int time;
    
    public:
        //静态属性的申明
        static int tag;
    
    public:
        //构造函数
        Student();
        Student(int age);
        Student(int time, int age);
    
        //析构函数
        ~Student();
        //拷贝构造函数 
        Student(const Student &student );
    
    
    public:
        void setAge(int age);
        void setTime(int time);
    
        int getAge();
        int getTime();
    
        void print() const;
        //静态函数
        static void changeTag(int tag_replease);
        //友元函数
        friend void changeAge(Student* stu,int age);
    
    };
    
    
    
    

    实现类 Student.cpp

    #include "stdafx.h"
    #include "Student.h"
    #include <iostream>
    
    
    //实现类,不一定都要全部实现
    
    
    //静态属性的申明
    int Student::tag = 0;
    
    
    //构造函数
    Student::Student(){ 
        
    };
    
    Student::Student(int age):time(200) { //time默认赋值
        this->age = age;
    }
    
    Student::Student(int age,int time) { 
        this->age = age;
        this->time = time;
    }
    
    //析构函数
    Student::~Student() {
        //资源回收
    }
    //拷贝构造函数
    Student::Student(const Student& student) {
    
    }
    
    //普通方法
    void Student::setAge(int age) {
        this->age = age;
    }
    void  Student::setTime(int time) {
        this->time = time;
    }
    
    int  Student::getAge() {
        return  this->age;
    }
    int Student::getTime() {
        return  this->time;
    }
    
    // const函数
    void Student::print() const {
        //this->age = 20;//不能操作this
            std::cout << this->age << "  " << this->time << "   "<< tag << std::endl;
    }
    
    //静态函数
    void Student::changeTag(int tag_replease) {
        tag = tag_replease;
    }
    
    //友元函数  不需要加 Student::
    void changeAge(Student* stu, int age) {
        stu->age = age;
    }
    
    
    

    demo:

    #include "stdafx.h"
    #include "Student.h"
    
    
    void main() {
        Student* stu = new Student(24, 1000);
        //调用const函数
        stu->print();
    
        //调用静态函数
        Student::changeTag(36);
        stu->print();
    
        //调用友元函数
        changeAge(stu, 37);
        stu->print();
    
    
        delete(stu);
    
        getchar();
    }
    
    

    友元类 :java的反射获取属性可以理解为就是有一个Class类的友元类

    class ImageView {
     public:
         //申明Class是ImageView 的友元类
         friend class Class;
     private:
         int age;
    };
    
     class Class{
     public:
         void changeAge(int age) {
             //正常情况下这是不能直接用的,申明友元类就可以用了
              aObj.age = age;
         }
    
        int getAge() {
            //正常情况下这是不能直接用的,申明友元类就可以用了
             return aObj.age;
         }
     private :
         ImageView aObj;
     };
    
    
     void main() {
         Class b;
         b.changeAge(10);
         std::cout << b.getAge() << std::endl; // 10
         getchar();
     }
    

    操作运算符

    
    #include <iostream>
    
    using namespace std;
    
    
    class  Vector
    {
    public:
        Vector(int x, int y){
            this->x = x;
            this->y = y;
        }
    
        Vector(const Vector &vector){
            this->x = vector.x;
            this->y = vector.y;
            cout << "拷贝构造函数" << endl;
        }
    private:
        int x;
        int y;
    
    public:
        void setX(int x){
            this->x = x;
        }
        void setY(int y){
            this->y = y;
        }
    
        int getX(){
            return this->x;
        }
        int getY(){
            return this->y;
        }
    
        // 重载减号运算符
        // 为什么要用引用,为了防止重复创建对象
        // const 关键常量,为了防止去修改值
        Vector operator - (const Vector &vector){
            int x = this->x - vector.x;
            int y = this->y - vector.y;
            Vector res(x, y);
            return res;// 不建议返回引用
        }
    
        // 自增减运算符
        void operator ++ (){// ++X
            this->x = this->x++;
            this->y = this->y++;
        }
    
        void operator ++ (int){// X++
            this->x = this->x++;
            this->y = this->y++;
        }
    
        // 自减
        // 输出运算符
        friend ostream & operator << (ostream &_Ostr, const Vector &vector){
            _Ostr << vector.x << "," << vector.y << endl;
            return _Ostr;
        }
    
        // 条件运算符
        bool operator == (const Vector &vector){
            return (this->x == vector.x && this->y == vector.y);
        }
    };
    
    // 定义在类的外面,一般来讲我们定义在类的里面
    // 重载运算 + :operator +
    Vector operator + (Vector vector1, const Vector vector2){
        int x = vector1.getX() + vector2.getX();
        int y = vector1.getY() + vector2.getY();
        Vector vector(x,y);
        return vector;
    }
    
    void main(){
        Vector vector1(2, 3);
        Vector vector2(2, 3);
    
        // java 中 string + string 
    
        // char* str = "123" + "456";
    
        // 重载运算符 +
        // Vector vector = vector1 - vector2;
    
        // Vector vector(1, 2);
        // vector++;
        // ++vector;
    
        // cout << vector.getX() << " , " << vector.getY() << endl;
        // cout << vector << vector;
        bool isEqual = vector1 == vector2;
        cout << isEqual << endl;
    
        // 可以重载加其他对象 Person
    
        getchar();
    }
    
    
    
    // 括号运算符
    class Array
    {
    public:
        Array(int size){
            this->size = size;
            this->array = (int*)malloc(sizeof(int)*size);
        }
        ~Array(){
            if (this->array){
                free(this->array);
                this->array = NULL;
            }
        }
    
        Array(const Array& array){
            this->size = array.size;
            this->array = (int*)malloc(sizeof(int)*array.size);
    
            // 值的赋值
            for (int i = 0; i < array.size; i++)
            {
                this -> array[i] = array.array[i];
            }
        }
    
    private:
        int size;
        int* array;
    
    public:
        void set(int index,int value){
            array[index] = value;
        }
    
        int get(int index){
            return this->array[index];
        }
    
        int getSize(){
            return this->size;
        }
    
        // 操作符[]
        int operator[](int index){
            return this->array[index];
        }
    };
    
    void printfArray(Array array){
        for (int i = 0; i < array.getSize(); i++)
        {
            cout << array[i] << endl;
        }
    }
    
    void main(){
        
        Array *array = new Array(5);
    
        array->set(0,0);
        array->set(1, 1);
        array->set(2, 2);
    
        printfArray(*array);
    
        delete(array);
        getchar();
    }
    
    
    

    类的继承 : 类继承,构造函数调用顺序:先父类 -> 再子类 ,析构函数调用顺序 : 先子类 -> 再父类

    
    // 初始化属性
    class Person{
        // 变量修饰符
    public:// 本类中使用
        // protected :子类中能使用 (默认)
        // public :公开,任何地方都可以
        char* name;
        int age;
    
    public:
        Person(char* name, int age){
            this->name = name;
            this->age = age;
            cout << "Person 构造函数" << endl;
        }
    
    public:
        void print(){
            cout << this->name << " , " << this->age << endl;
        }
    };
    
    
    class Student : public Person
    {
    private:
        char* courseName;
    public:
        // : Person(name,age) 调用构造函数初始化父类的属性
        // 不光可以给父类初始化属性,还可以给本类的属性进行初始化,用 , 隔开即可
        Student(char* name, int age, char* courseName) :Person(name, age), courseName(courseName){// 调用父类构造函数
            cout << "Student 构造函数" << endl;
        }
    
        void print(){
            cout << "courseName: " << courseName << endl;
        }
    };
    
    class Teacher: public Person
    {
    public:
        Teacher(char*name,int age):Person(name,age){
            
        }
    };
    
    void main(){
        Student stu("张三",24,"语文");
        stu.print();
        getchar();
    }
    
    
    #include <iostream>
    using namespace std;
    
    class Person {
    protected:
        char* name;
        int age;
    public:
        Person(char* name, int age){
            this->name = name;
            this->age = age;
        }
    };
    
    class Course
    {
    private:// java String
        string name;
    public:
        Course(string name){
            this->name = name;
        }
    
    public:
        string _name(){
            return this->name;
        }
    };
    
    
    class Student : public Person
    {
    private:
        Course course;
    public:
        Student(char* name, int age, string courseName) : Person(name, age), course(courseName){ // 初始化父类的属性
        }
    
        void print(){
            cout << name << "," << age << "," << course._name().c_str() << endl;
        }
    };
    
    

    多继承

    #include <iostream>
    using namespace std;
    
    class Person{
    private:
        char * name;
    
    public:
        Person(char * name){
            this->name = name;
        }
    
        char* _name(){
            return this->name;
        }
    };
    
    class Child
    {
        int age;
    public:
        Child(int age){
            this->age = age;
        }
    
        int _age(){
            return this->age;
        }
    };
    
    // 多继承,在 java 里面是不允许多继承 , c++ 是可以的,但是你也不能有二义性(歧义)
    class Student : public Person, public Child // 多继承 , 并没有实现(接口)
    {
    public:
        Student(char* name,int age):Person(name),Child(age){
    
        }
    };
    
    

    虚继承:解决二义性

    class A{
    public:
        char* name;
    };
    
    class B : virtual public A{ // virtual 确保继承过来的相同属性或者函数,只存在一份拷贝
    
    };
     
    class C :virtual public A{
    
    };
    
    class D : public B ,public C
    {
    
    };
    
    
    

    多态:c++里面分为动态多态(子父类 需要virtual修饰),静态多态(函数的重载),区别是编译过程确定性。

    class Activity
    {
    public:
        virtual void onCreate(){ // 支持多态,虚函数
            cout << "Activity 中的 onCreate" << endl;
        }
    };
    
    class MainActivity : public Activity
    {
    public:
        void onCreate(){
            cout << "MainActivity 中的 onCreate" << endl;
        }
    };
    
    class WelcomeActivity : public Activity
    {
    public:
        void onCreate(){
            cout << "WelcomeActivity 中的 onCreate" << endl;
        }
    };
    
    void startActivity(Activity* activity){
        activity->onCreate();
    }
    
    void main(){
        Activity *activity1 = new MainActivity();// 父类 = new 子类对象
        Activity *activity2 = new WelcomeActivity();
    
        // activity->onCreate();
        // c++ 中的多态是怎样的,默认情况下不存在
        // 父类指向子类的引用,重写 ,里氏替换原则 
        // 程序在编译期间并不知晓运行的状态(我需要运行那个函数),只要在真正运行的过程中才会去找需要运行的方法
        startActivity(activity1);//如果Activity里面onCreate不加virtual,那么将会执行Activity的onCreate不会执行MainActivity的onCreate
        startActivity(activity2);
    
        // c++ 多态:动态多态(子父类),静态多态(函数的重载)(编译过程确定性的区别)
    
        getchar();
    }
    

    抽象类,抽象函数

    // java 中类似的 抽象类,接口 纯虚函数
    class BaseActivity // 跟 java 中的抽象类一个概念
    {
    public:
        void onCreate(){// 普通函数
            initView();
            initData();
        }
    
        // 子类必须要实现 
        virtual void initData() = 0;// 虚函数,没有实现的,类似于 java 中的抽象方法,如果子类不实现会报错
    
        virtual void initView() = 0;
    
    };
    
    // 如果不实现父类的纯虚函数,那么 MainActivity 也会变成抽象类,抽象类不允许实例化
    class MainActivity : public BaseActivity 
    {
    public:
        void initData(){
            cout << "initData" << endl;
        }
    
        void initView(){
            cout << "initView" << endl;
        }
    };
    
    void main(){
        
        BaseActivity *m_a = new MainActivity();
    
        m_a->onCreate();
    
        getchar();
    }
    
    

    接口

    
    class ClickListener{// 所有的函数都是虚函数,那么就可以认为是接口
    public:
        virtual void click() = 0;
    };
    
    class ImageClickListener : public ClickListener
    {
    public :
        void click(){
            cout << "图片点击" << endl;
        }
    };
    
    void main(){
        // 函数指针的时候:回调可以用 指针函数作为回调,纯虚函数类进行回调(接口)
        // ClickListener *listener = new ImageClickListener();
    
        //直接调用
        // listener->click();
    
        getchar();
    }
    
    

    模板函数 : java 中的泛型

    // 模板函数的定义
    template <typename T> T add(T number1, T number2){
        return number1 + number2;
    }
    
    void main(){
        
        int sum1 = add(1,2);
    
        cout << sum1 << endl;
    
        int sum2 = add(1.0, 2.0);
    
        cout << sum2 << endl;
    
        int sum3 = add(1.0f, 2.0f);
    
        cout << sum3 << endl;
    
        getchar();
    }
    
    

    模板类

    template <typename T> class Callback{
    public:
        void onError(){
            
        }
    
        void onSucceed(T result){
            cout << result << endl;
        }
    };
    
    // 模板类继承 ,子类如果也是模板类
    // 如果子类不是模板类
    class HttpCallback : public Callback<int>{
        
    };
    
    template <class T>
    class HttpCallback : public Callback<T>{
    
    };
    
    void main(){
        HttpCallback<int> *callback = new HttpCallback<int>();
    
        callback->onSucceed(12);
    
        getchar();
    }
    
    

    如果开发中涉及到模板类,申明和实现要写在同一个类里面: hpp = h + cpp/c (编译)

    例如:c++实现ArrayList

    ArrayList.hpp

    #include <malloc.h>
    //------------------类的定义-------------------//
    
    template<class E>
    class ArrayList {
    public:
        // 数组头指针
        E *array = NULL;
        // 数组长度
        int len = 0;
        // 数据大小
        int index = 0;
    public:
        ArrayList();
    
        ArrayList(int len);
    
        ~ArrayList();
    
        ArrayList(const ArrayList &list);
    
    public:
        bool add(E e);
    
        int size();
    
        E get(int index);
    
        E remove(int index);
    
    private:
        void ensureCapacityInternal(int i);
    
        void grow(int capacity);
    };
    
    //------------------类的实现-------------------//
    template<class E>
    ArrayList<E>::ArrayList() {
    
    }
    
    template<class E>
    ArrayList<E>::ArrayList(int len) {
        if (len == 0) {
            return;
        }
        this->len = len;
        this->array = (E *) malloc(sizeof(E) * len);
    }
    
    template<class E>
    ArrayList<E>::~ArrayList() {
        if (this->array) {
            free(this->array);
            this->array = NULL;
        }
    }
    
    template<class E>
    ArrayList<E>::ArrayList(const ArrayList &list) {
        this->index = list.index;
        this->len = list.len;
        // 深拷贝
        this->array = (E *) malloc(sizeof(E) * len);
        memcpy(this->array,list.array,sizeof(E) * len);
    }
    
    template<class E>
    E ArrayList<E>::get(int index) {
        return this->array[index];
    }
    
    template<class E>
    int ArrayList<E>::size() {
        return this->index;
    }
    
    template<class E>
    E ArrayList<E>::remove(int index) {
        E old_value = this->array[index];
        // 计算出需要逻动的个数
        int numMoved = this->index - index - 1;
    
        // 从前面不断的逻动
        for (int i = 0; i < numMoved; ++i) {
            array[index + i] = array[index + i + 1];
        }
    
        this->index -= 1;
        return old_value;
    }
    
    template<class E>
    bool ArrayList<E>::add(E e) {
        ensureCapacityInternal(index + 1);
        this->array[index++] = e;
        return true;
    }
    
    // 是否需要调整当前数组大小
    template<class E>
    void ArrayList<E>::ensureCapacityInternal(int minCapacity) {
        // 当前数组是不是空,或者 len 是不是 0
        if (this->array == NULL) {
            minCapacity = 10;// 第一次初始化大小
        }
    
        // 判断要不要扩容
        if (minCapacity - len > 0) {
            grow(minCapacity);
        }
    }
    
    // 扩容创建新的数组
    template<class E>
    void ArrayList<E>::grow(int capacity) {
        // 计算新数组大小的长度
        int new_len = len + (len >> 1);
    
        if (capacity - new_len > 0) {
            new_len = capacity;
        }
    
        // 创建新的数组
        E *new_arr = (E *) malloc(sizeof(E) * new_len);
    
        if (this->array) {
            // 拷贝数据
            memcpy(new_arr, array, sizeof(E) * index);
            // 释放原来的内存
            free(this->array);
        }
    
        array = new_arr;
        len = new_len;
    }
    
    
    

    使用的时候引入ArrayList.hpp

    #include "ArrayList.hpp"
    #include <jni.h>
    #include <string>
    #include <android/log.h>
    
    #include "ArrayList.hpp"
    
    extern "C"
    JNIEXPORT void
    JNICALL
    Java_com_zzw_demo_MainActivity_test(
            JNIEnv *env,
            jobject /* this */) {
    
        ArrayList<int> *list = new ArrayList<int>();//
    
        for (int i = 0; i < 100; ++i) {
            list->add(i);
        }
    
        for (int i = 0; i < list->size(); ++i) {
            __android_log_print(ANDROID_LOG_ERROR,"TAG","i = %d",list->get(i));
        }
    
        delete(list);
    }
    
    
    

    异常处理

    
    class Exception
    {
    public:
        string msg;
    
    public:
        Exception(string msg){
            this->msg = msg;
        }
    
    public:
        const char *what(){
            return this->msg.c_str();
        }
    
    };
    
    // 异常的处理
    void main(){
        // c++ 中有自己一套异常的体系,不要去强记
        // 但是 c++ 可以抛任何数据类型 try{}catch(数据类型 变量名){}
        // throw 抛异常
    
         try{
            int i = -1;
    
            if (i == 0){
                throw Exception("出异常了");
            }
    
            if (i< 0){
                throw 12.5f;
            }
         }
        catch (int number){
            cout << "捕捉到异常" <<number << endl;
        }
        catch (Exception exception){
            cout << "捕捉到异常:" << exception.what() << endl;
        }
        catch (...){
            cout << "捕捉到其他异常:" << endl;
        }
    
        getchar();
    }
    
    

    字符串常见操作

    创建

    void main(){
    
        string str1 = "123";
        string str2("123");
        string str3(5, 'A');// 5 个 A = AAAAA
        string *str4 = new string("123");
    
        // cout << str1.c_str() <<endl;
        // cout << str2.c_str() << endl;
        // cout << str3.c_str() << endl;
        // cout << str4->c_str() << endl;
    
        // string 与 char* 相互之间转换 c_str()
        // const char* c_str1 = str1.c_str();
        // cout << c_str1 << endl;
    
        // char* -> string
        char* c_str = "张三";
        string str(c_str);// 对象
        cout << str.c_str() << endl;
    
    
        getchar();
    }
    
    

    遍历

    void main(){
    
        string str("1234567");
    
        // 1. 字符串的遍历
        for (int i = 0; i < str.length(); i++)
        {
            cout << str[i] << endl;
        }
    
        // 迭代器遍历
        for (string::iterator it = str.begin(); it < str.end(); it++)
        {
            cout << *it << endl;
        }
    
        try{
            for (int i = 0; i < str.length()+2; i++)
            {
                cout << str.at(i) << endl;// 如果越界会抛异常
            }
    
            for (int i = 0; i < str.length()+2; i++)
            {
                cout << str[i] << endl;// 会导致程序宕机,AS里面是可以的
            }
        }
        catch (...){
            cout << "异常了" << endl;
        }
    
        getchar();
    }
    
    

    添加

    void main(){
    
        // 添加
        string str1 = "123";
        string str2 = "456";
    
        // str1 = str1 + str2;
        // str1.append(str2);
    
    
        cout << str1.c_str() << endl;
    
        getchar();
    }
    
    
    

    删除

    void main(){
    
        // 删除
        string str1 = "123 abc 123 abc 123";
    
        // str1.erase(0,3);// 第一个参数:从哪里开始 ; 第二个参数:删除几个(默认值,字符串的结尾)
    
        // 迭代器删除  2 bc 123 abc 123 解释  第一次删除第一个位置1,变为23 abc....  ,第二次删除第二个位置3,变为2 abc.... ,第三次删除第三个位置a,就是2 bc ....
        for (string::iterator it = str1.begin(); it<str1.begin()+3; it++)// 删除一个字后都会从头开始计算
        {
            str1.erase(it);
        }
    
        cout << str1.c_str() << endl;
    
        getchar();
    }
    
    

    替换

    void main(){
    
        string str1 = "123 abc 123 abc 123";
        // 第一个参数:从哪里开始
        // 第二个参数:替换几个
        // 第三个参数:替换成谁
        str1.replace(0,6,"1234");
    
        cout << str1.c_str() << endl;
    
        getchar();
    }
    
    

    查找

    
    void main(){
    
        string str1 = "123 abc 123 abc 123";
        // 查找谁,从哪里开始
        // int position = str1.find("123",0);
        // 从后面往前面查
        int position = str1.rfind("123");
    
        cout << position << endl;
    
        getchar();
    }
    
    

    大小写转换

    void main(){
    
        string str1 = "AAA abc BBB abc 123";
        // 转换成大写
        // transform(str1.begin(), str1.end(), str1.begin(), toupper);
    
        transform(str1.begin(), str1.end(), str1.begin(), tolower);
    
        cout << str1.c_str() << endl;
    
        getchar();
    }
    
    
    

    STL标准模板库 : 容器+迭代+算法

    • 思想:集合,迭代器,算法 进行分离

    vector容器(数组)

    https://zh.cppreference.com/w/cpp/container/vector

    容量
    
        向量大小: vec.size();
        向量真实大小: vec.capacity();
        向量判空: vec.empty();
    
    
    修改
    
        末尾添加元素: vec.push_back();
        末尾删除元素: vec.pop_back();
        任意位置插入元素: vec.insert();
        任意位置删除元素: vec.erase();
        清空向量元素: vec.clear();
    
    
    迭代器
        开始指针:vec.begin();
        末尾指针:vec.end(); //指向最后一个元素的下一个位置
        指向常量的末尾指针: vec.cend();
    
    
    元素的访问
        下标访问: vec[1]; //并不会检查是否越界
        at方法访问: vec.at(1); //以上两者的区别就是at会检查是否越界,是则抛出out of range异常
        访问第一个元素: vec.front();
        访问最后一个元素: vec.back();
    
    
    
    

    stack容器(链表,数组)
    https://zh.cppreference.com/w/cpp/container/stack

    queue容器(数组,链表)
    https://zh.cppreference.com/w/cpp/container/queue

    list容器(链表)
    https://zh.cppreference.com/w/cpp/container/list

    set容器(红黑树,元素不重复)
    https://zh.cppreference.com/w/cpp/container/set

    multiset容器(元素可重复)
    https://zh.cppreference.com/w/cpp/container/multiset

    map容器(key不能重复)
    https://zh.cppreference.com/w/cpp/container/map

    multimap容器(以key分组)
    https://zh.cppreference.com/w/cpp/container/multimap

    对象添加到容器需要注意的:

    1. java 中把对象添加到了集合,c++ 中会调用对象的拷贝构造函数,存进去的是另一个对象
    2. 在c++中将对象加入到容器,需要有默认的构造函数
    3. 析构函数也可能回调用多次,如果说在析构函数中释放内存,需要在拷贝构造函数中进行深拷贝

    仿函数

    
    class Compare{
        // 重载了括号运算符
    public:
        void operator()(){
            cout << "仿函数" << endl;
        }
    };
    
    void compare1(){
        cout << "普通函数" << endl;
    }
    
    // 函数对象(仿函数) 一元谓词,二元谓词
    void main(){
        Compare compare;
    
        // 跟函数非常类似
        compare();//打印“仿函数”
        // 普通函数调用
        compare1();
    
        getchar();
    }
    
    

    谓词

    一元谓词

    
    // 一元谓词
    void print(int number){
        cout << number << endl;
    }
    
    // 仿函数 - 一元谓词 (能够记录状态)
    class PrintObj
    {
    public:
        int count = 0;
    public:
        void operator()(int number){
            cout << number << endl;
            count++;
        }
    };
    
    // 回调函数和仿函数的区别
    void main() {
    
        set<int> set1;
        set1.insert(1);
        set1.insert(2);
        set1.insert(3);
        set1.insert(4);
    
        // for_each 迭代器 ,非常重要的一点就是:仿函数如果要保存记录状态,要确保对象一致,可以用返回值
        // for_each(set1.begin(),set1.end(),print);//会打印
        PrintObj printObj;
        //for_each(set1.begin(), set1.end(), printObj);
        //cout << "个数:" << printObj.count << endl; //个数:0 ,要确保对象一致
        printObj = for_each(set1.begin(), set1.end(), printObj);
        cout << "个数:" << printObj.count << endl; //个数:4 ,对象一致
    
        getchar();
    }
    
    
    

    二元谓词

    
    #include <set>
    #include <iostream>
    
    using namespace std;
    
    class CompareObj{
    public:
        int count = 0;
    public:
        bool operator()(const string str1, const string str2) {
            return str1 > str2;
        }
    };
    
    void main() {
        // 二元谓词的仿函数
        set<string, CompareObj> set1;
        set1.insert("aaa");
        set1.insert("aAa");
        set1.insert("ccc");
        set1.insert("ddd");
        // 是否包含 aaa , 遍历比较 , 找方法
        for (set<string>::iterator it = set1.begin(); it != set1.end(); it++)
        {
            cout << (*it).c_str() << endl;
        }
        //ddd ccc aaa aAa
        getchar();
    }
    
    

    预定义函数对象(自定义重载 () 运算符),函数适配器

    #include<iostream>
    #include<vector>
    #include<set>
    #include<functional>
    #include<algorithm>
    
    using namespace std;
    
    
    // 自定义重载 () 运算符
    //预定义函数对象
    void main(){
        // c/c++ 提供了很多定义好的函数对象
        // 常见的几个 less ,greater,plus,equal_to
        plus<string> strAdd;
        string str = strAdd("aaa","bbb");
    
        // cout << str.c_str() << endl;
    
        set<string, greater<string>> set1;
        set1.insert("aaa");
        set1.insert("bbb");
        set1.insert("ccc");
    
        // 判断是不是包含 aaa 
        // 怎么写仿函数,一定要确定好你的仿函数的参数
        // bind2nd 函数适配器 , aaa 相当于 equal_to 中的 right 
        set<string, greater<string>>::iterator find_it = find_if(set1.begin(), set1.end(),bind2nd(equal_to<string>(),"aaa"));
        if (find_it != set1.end()){
            cout << "找到了" << (*find_it).c_str() << endl;
        }
        else
        {
            cout << "没有找到" << endl;
        }
    
        getchar();
    }
    
    
    #include<iostream>
    #include<vector>
    #include<set>
    #include<functional>
    #include<algorithm>
    
    using namespace std;
    
    class Equal
    {
    private:
        int equal_number;
    public:
        Equal(int equal_number) {
            this->equal_number = equal_number;
        }
    public:
        bool operator()(const int& number) {
            return number == equal_number;
        }
    };
    
    void main() {
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
        vector1.push_back(2);
        vector1.push_back(4);
        vector1.push_back(2);
    
        // 找集合中 等于 2 的个数
        int count = count_if(vector1.begin(), vector1.end(), Equal(2));
        cout << "count = " << count << endl;
    
        // 预定义好的函数对象 + 函数适配器
        count = count_if(vector1.begin(), vector1.end(), bind2nd(equal_to<int>(), 2));
        cout << "count = " << count << endl;
    
        getchar();
    }
    
    
    • foreach,transform
    #include<iostream>
    #include<vector>
    #include<set>
    #include<functional>
    #include<algorithm>
    
    using namespace std;
    
    void print(int number) {
        cout << number << endl;
    }
    
    // 进行修改
    int transform_print(int number) {
        // cout << number << endl;
        return number + 3;
    }
    
    // foreach,transform,find,find_if,count,count_if,megre,sort,random_shuffle,copy,replace
    // 常用预定义算法 循环,增,删,改,    
    void main() {
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
        vector1.push_back(4);
    
        //for_each循环
        // for_each(vector1.begin(), vector1.end(),print); //1234
        vector<int> vector2;
        vector2.resize(vector1.size());
    
        //变换和循环
        transform(vector1.begin(), vector1.end(), vector2.begin(), transform_print);//4567
    
        for_each(vector2.begin(), vector2.end(), print);
    
        getchar();
    }
    
    
    • find,find_if
    #include<iostream>
    #include<vector>
    #include<set>
    #include<functional>
    #include<algorithm>
    
    using namespace std;
    
    void print(int number) {
        cout << number << endl;
    }
    
    // 进行修改
    int transform_print(int number) {
        // cout << number << endl;
        return number + 3;
    }
    
    // foreach,transform,find,find_if,count,count_if,megre,sort,random_shuffle,copy,replace
    // 常用预定义算法 循环,增,删,改,    
    void main() {
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
        vector1.push_back(4);
    
        vector<int>::iterator find_it = find(vector1.begin(), vector1.end(), 2);
    
        if (find_it != vector1.end()){
            cout << "包含" << endl;
        }
        else
        {
            cout << "不包含" << endl;
        }
    
        // 有没有大于2的,自定义函数对象,预定义函数对象+函数适配器,省略...
        //findif() //上面有
        getchar();
    }
    
    
    • count,count_if
    
    void main(){
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
        vector1.push_back(2);
        vector1.push_back(4);
    
        int number = count(vector1.begin(), vector1.end(), 2);
    
        cout << "等于2的个数:" << number << endl;
    
        number = count_if(vector1.begin(), vector1.end(), bind2nd(less<int>(), 2));
    
        cout << "小于2的个数:" << number << endl;
    
        number = count_if(vector1.begin(), vector1.end(), bind2nd(greater<int>(), 2));
    
        cout << "大于2的个数:" << number << endl;
    
        getchar();
    }
    
    
    • megre: 两个有序数组进行合并 - 归并排序
    
    using namespace std;
    
    
    void print(int number) {
        cout << number << endl;
    }
    
    // megre,sort,random_shuffle,copy,replace
    void main() {
    
        // 两个有序数组进行合并 - 归并排序
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
    
        vector<int> vector2;
        vector1.push_back(4);
        vector1.push_back(5);
        vector1.push_back(6);
    
        vector<int> vector3;
        vector3.resize(6);
        merge(vector1.begin(), vector1.end(), vector2.begin(), vector2.end(), vector3.begin());
        for_each(vector3.begin(), vector3.end(), print);
    
        getchar();
    }
    
    
    • soft,random_shuffle
    void print(int number) {
        cout << number << endl;
    }
    
    // sort,random_shuffle
    void main() {
    
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(3);
        vector1.push_back(2);
        vector1.push_back(4);
    
        sort(vector1.begin(), vector1.end(), less<int>());
        for_each(vector1.begin(), vector1.end(), print);
    
        cout << "循环结束" << endl;
    
        // 打乱循序 
        random_shuffle(vector1.begin(), vector1.end());
        for_each(vector1.begin(), vector1.end(), print);
    
        getchar();
    }
    
    
    • copy,replace
    
    void print(int number) {
        cout << number << endl;
    }
    
    //copy,replace
    void main() {
    
        vector<int> vector1;
        vector1.push_back(1);
        vector1.push_back(2);
        vector1.push_back(3);
        vector1.push_back(4);
    
        vector<int> vector2;
        vector2.resize(2);
        copy(vector1.begin(), vector1.begin() + 2, vector2.begin());
         for_each(vector2.begin(), vector2.end(), print);
    
        replace(vector1.begin(), vector1.end(), 2, 22);
        for_each(vector1.begin(), vector1.end(), print);
    
        getchar();
    }
    

    相关文章

      网友评论

        本文标题:c++基础语法

        本文链接:https://www.haomeiwen.com/subject/ciawmftx.html