美文网首页
NDK—C++类

NDK—C++类

作者: Lypop | 来源:发表于2017-10-30 23:58 被阅读0次

    上一篇我们学习了C++的命名空间,这篇我们来了解一下C++的构造和析构函数

    废话不多说,开始撸码

    正文

    构造函数、析构函数、拷贝构造函数

    来个简单的例子,了解一下构造和析构的写法

    class Teacher{
        public:
            int age;
        public:
            Teacher(){
                cout << "无参构造函数" << endl;
            }
            ~Teacher(){
                cout << "析构函数" << endl;
            }
        };
    

    当类没有构造函数的时候默认会有一个无参的构造函数,构造函数的作用是初始化变量,析构函数则释放资源

    既然有了构造函数,那怎么创建对象呢?

    无参构造:   Teacher t;
    有参构造:   Teacher t1("lypop", 21);
                Teacher t2 = Teacher("lypop", 21);
    创建指针:   Teacher *tt = new Teacher("lypop",21);
    

    对于析构函数的调用,我们将创建放在一个方法里面,当方法执行结束便会执行析构函数

    class Teacher{
    private:
        char *name;
        int age;
    public:
        Teacher(){
            this->name = (char*)malloc(100);
            strcpy(name, "lypop");
            age = 20;
            cout << "无参构造函数" << endl;
        }
        
        //析构函数
        ~Teacher(){
            cout << "析构" << endl;
            //释放内存
            free(this->name);
        }
    };
    
    void func2(){
        Teacher t;
    }
    

    我们只需要在析构函数中释放相应的资源

    除了构造函数和析构函数,类里面有个默认的拷贝构造函数,它只是一种值拷贝,当类中有指针属性的时候容易发生崩溃。所以当我们类中有指针需要在析构函数释放资源的时候,拷贝构造函数都使用深拷贝

    下面来看一下值拷贝(浅拷贝)

    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 func(){
        Teacher t1("rose", 20);
    
        Teacher t2 = t1;//这时候会调用默认的拷贝构造函数
    }
    

    当func执行完毕之后就会调用两次析构,因为只是简单的值拷贝,name指针指向的是同一块内存地址,当第一个被释放掉在释放第二个的时候就会出错。所以需要解决这种就需要深拷贝,也就是重写拷贝构造函数为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;
    }
    

    拷贝构造函数被调用的场景:

    1. 声明时赋值
    2. 作为参数传入,实参给形参赋值
    3. 作为函数返回值返回,给变量初始化赋值
    C和C++创建指针和释放资源
    C  创建 int *p1 = (int*)malloc(sizeof(int) * 10);
       释放 free(p1);
    
    C++创建 int *p2 = new int[10];
       释放 delete[] p2;//释放数组指针  delete p;//释放指针
    
    C++访问静态属性和方法

    通过类名::来访问,也可以通过类对象来访问

    int Teacher::total = 9;
    Teacher::total++;
    Teacher::count();
    
    常量对象、常函数

    Teacher *const this;能改变指针指向的内容,不能改变指针的值

    const Teacher* const this;既不能改变指针的值,又不能改变指针指向的内容

    常量对象只能调用常量函数,不能调用非常量函数。常函数当前对象不能被修改,防止数据成员被非法访问

    class Teacher{
        void myprint() const{
            
        }
    };
    void main(){
        const Teacher t1("aaa",22);
    
        t.myprint(); 
    
        system("pause");
    
    }
    
    友元函数、友元类

    友元函数的实现,在友元函数中可以访问私有的属性

    class A{
    friend void modify_i(A *p, int a);
    private:
        int i;
    };
    void modify_i(A *p, int a){
        p->i = a;
    }
    

    友元类中可以访问友元对象所在类的所有成员

    class A{
    friend class B;
    private:
        int i;
    
    };
    
    class B{
    public:
        //B这个友元类可以访问A类的任何成员
        void accessAny(){
            a.i = 30;
        }
    private:
        A a;
    };
    
    运算符重载
    1. 类外进行运算符重载

       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;
       }
      
    2. 类内进行运算符重载

       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;
           }
           };
      
    3. 当属性私有的时候需要使用友元函数实现运算符重载

       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;
       }
      

    但是运算符重载的本质还是函数的调用,至此C++的类就总结到这里,谢谢不耐其烦的看完。

    相关文章

      网友评论

          本文标题:NDK—C++类

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