• c++对类的的详解(2)


    知识点13【explicit关键字】

    c++提供了关键字explicit,禁止通过构造函数进行隐式转换。声明为explicit的构造函数不能在隐式转换中使用。

    #include 
    
    using namespace std;
    
    
    class Data
    {
    private:
        int num;
    public:
        Data()
        {
            cout<<"Data无参构造"<<endl;
        }
    
            //初始化列表:对象名+() 显示调用 调用对象成员的构造函数
        explicit Data(int a):num(a)
        {
            //data =c;
            cout<<"Data有参构造"<<endl;
        }
        ~Data()
        {
            cout<<"Data析构函数"<<endl;
        }
    
    };
    
    int main(int argc, char *argv[])
    {
        //当explicit修饰构造函数,不允许隐式转换
        Data data = 10;
        Data data1(15);//ok
        Data data2 = Data(20);//ok
        cout << "Hello World!" << endl;
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    运行结果:
    在这里插入图片描述

    知识点14【new和delete】从堆区申请空间

    1、和malloc 、calloc、realloc比较

    (1)malloc返回一个void指针,c++不允许将void赋值给其他任何指针,必须强转。
    (2)malloc可能申请内存失败,所以必须判断返回值来确保内存分配成功。
    (3)maloc不会调用构造函数,free不会调用析构函数(重要的)

    2、new给基本类型申请空间

    void test01(){
        int* a = new int;
        *a = 100;
        cout<<"*a = "<<*a<<endl;//100
        delete a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    new申请基本类型空间

    void test02(){
        int *a = new int[5];//申请内容的时候,内容没有初始化,值随机。
        int *b = new int[5]{1,2,3,4,5};//值初始化。
        for(int i = 0; i < 5; i++){
            cout << a[i] << " ";
        }
        cout << endl;
        delete [] a;//new时加了[],delete也必须加[].
        for(int i = 0; i < 5; i++){
            cout << b[i] << " ";
        }
        cout << endl;
        delete [] b;
    
        //char *b = new char[15]{"hehe"};//错误
        char *arr = new char[15];
        strcpy(arr,"hehe");
        cout << arr << endl;
        delete [] arr;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果:
    在这里插入图片描述
    注意:(1)new没有加[],delete释放的时候就不加[].
    (2)new加[],delete释放的时候就加[].

    3、new和delete给类对象申请空间

    void test03(){
        //new按照Data申请空间,如果申请成功,会自动调用构造函数。
        Data *data = new Data();
        
        //先调用析构函数,在释放空间
        delete data;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果:
    在这里插入图片描述

    class Data
    {
    private:
        int num;
        char *str;
    public:
        Data()
        {
            cout<<"Data无参构造"<<endl;
        }
    
        //初始化列表:对象名+() 显示调用 调用对象成员的构造函数
        Data(int a,char *str1):num(a),str(str1)
        {
            cout<<"Data有参构造"<<endl;
        }
        ~Data()
        {
            cout<<"Data析构函数"<<endl;
        }
        void showData(){
            cout << num << " " << str << endl;
        }
    };
    
    void test04(){
        Data *data = new Data(100,"hehe");
        
        //因为data是指针,所以使用->,如果是普通对象,则使用.
        data->showData();
    
        delete data;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:
    在这里插入图片描述

    知识点15【对象数组】

    本质还是数组,只是数组的每个元素是类的对象

    void test05(){
        char *data = "hehehehe";//该方法只适合于字符串。char *data = {'w','s'}的方法是错误的,其他类型这样创建数组也是错误的。
        int arr[3];
        //对象数组arr1是数组,每个元素是Data类型的对象。
        //定义对象数组的时候,系统会自动给的数组中的每个元素调用构造函数。
        //自动调用无参构造
        Data arr1[5];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行结果:
    在这里插入图片描述

    2、如果让对象数组中的元素调用有参构造,必须人为使用有参构造初始化

    void test06(){
    	//对象数组arr1是数组,每个元素是Data类型的对象
    	//定义对象数组的时候 系统会自动给数组中的每个元素调用构造函数
    	//人为为元素调用有参构造
    	//初始化部分 调用有参构造 未初始化部分自动调用默认构造(无参构造)
        Data arr2[5] = {Data(50,"haha"),Data(60,"xixi")};
        //arr2[0]第0个元素,就是Data的对象
        arr2[0].showData();
        arr2[1].showData();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果:
    在这里插入图片描述

    3、用new和delete申请对象数组

    void test07(){
        Data *arr1 = new Data[5];//调用无参构造
        delete [] arr1;
    
        //第二种方法,调用有参构造
        Data *arr2 = new Data[5]{Data(50,"haha"),Data(60,"xixi")};
        
        //访问数组的不同方式
        (*arr2).showData();
        arr2[0].showData();
        (arr2+1)->showData();
        delete [] arr1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果:
    在这里插入图片描述

    4、尽量不要用delete释放void*

    在这里插入图片描述
    注意:没有析构 ,这是因为data1指向的类型未void,无法从void中寻找响应析构函数
    在这里插入图片描述

    5、malloc、free、和new 、delete不能混搭使用

    知识点15【静态成员】static修饰的成员

    成员:成员变量、成员函数
    static修饰成员变量和成员函数
    static声明为静态的,称为静态成员。不管这个类创建了多少对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。
    静态成员属于类,而不是对象。
    在这里插入图片描述

    1、static修饰成员变量

    静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间
    静态变量必须在类内声明,类外定义(普通成员变量可以类内定义)。
    静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占的空间。

    class Data2{
    public:
        int num;//普通成员变量
        static int data;//静态成员变量
    
    };
    //定义的时候不需要加static
    int Data2::data = 100;
    
    
    void test(){
    
        //data是静态成员变量,是属于类的,可以通过类名称::直接访问
        cout << Data2::data << endl;//100
    
        //赋值
        Data2::data = 200;
        cout << Data2::data << endl;//200
    
       Data2 *ob1 = new Data2();
       //静态成员变量也可以使用对象名进行访问
       ob1->data = 300;
       cout << Data2::data << endl;//300
    
       Data2 *ob2 = new Data2();
       cout << ob2->data << endl;//300
    
       //普通成员变量只可以用成员名进行访问
       ob1->num = 100;
       cout << ob2->num << endl;//随机值
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2、static修饰静态成员函数

    class Data2{
    private:
        int num;//普通成员变量
        static int data;//静态成员变量
    public:
        //静态成员函数属于类而不属于对象
        static int getData(){
            return data;
        }
    
    };
    //定义的时候不需要加static
    int Data2::data = 100;
    
    void test10(){
        //静态成员函数可以通过类名直接访问
        cout << Data2::getData()<<endl;
        //也可以通过对象名进行访问
        Data2 *ob1 = new Data2();
        cout << ob-> getData() << endl;;
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注意:1、静态成员函数的目的是操作静态成员数据
    2、静态成员函数不能访问非静态成员数据。(静态成员函数内部没有this指针)
    在这里插入图片描述
    3、普通成员函数可以操作静态成员数据和非静态成员数据

    class Data2{
    private:
        int num;//普通成员变量
        static int data;//静态成员变量
    public:
        int getNum(){
            num = 100;//no-static
            return data;//static
        }
        static int getData(){
    
            return data;
        }
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4、静态成员变量和静态成员函数都有权限之分

    3、const修饰静态成员

    如果一个类的成员,既要实现共享,又要实现不可改变,那就用static const修饰

  • 相关阅读:
    openGauss本地Centos7.6单机安装和简单应用
    一、openCV+TensorFlow环境搭建
    nrm的安装以及使用
    c#与汇川plc通信
    Java注解Annotaton
    RestTemplate配置和使用
    RSSHub让万物皆可RSS
    java下标索引异常
    IDEA2021.2安装与配置(持续更新)
    深入理解Python中的Lambda(匿名函数)
  • 原文地址:https://blog.csdn.net/DUANJIAWEIDUANJIAWEI/article/details/126366812