• C++学习之 类


    1、类规范

    • 类声明:包括数据成员、成员函数(共有接口)的声明
    • 类方法定义

    C++程序员将接口(类)放在头文件中,将实现放在源代码文件中

    类设计尽量将共有接口和实现细节分开,数据隐藏(将数据放在私有部分中)是一种封装,将实现细节隐藏在私有部分中也是一种封装。将类函数定义和类声明放在不同文件中也是一种封装

    注:类方法默认是内联函数

     

    2、访问控制符

    类默认的访问控制符是private

     

    3、类和结构体

    类和结构的区别是:

    1、结构的默认访问类型是public,而类为private。

    2、结构体在声明变量时,可以直接像标准类型那样初始化,而类需要构造函数进行初始化,当所有成员变量都是public修饰时,可以像struct那样初始化对象

    如:

    int a = 2;
    struct node
    {
        int a;
        string s;
    };
    
    node n = {3,"abc"};
    Stock hot = {2,"abc"};//编译错误

     

     

    C语言中结构体不允许定义函数成员,且没有访问控制符的概念。

    C++为C语言中的结构体引入了成员函数、访问控制符、继承、包含多态等面向对象特性

    C++保留struct结构体原因:C++在struct之外引入了class关键字,但为了保持与C程序的兼容,C++保留了struct关键字,并规定默认访问权限为public

    另外,在C语言中,空结构体的大小为0,而在C++中空结构体(属于空类)的大小为1

    C++中空类的大小为1的原因:

    空类也可以实例化,类实例化出的每个对象都需要有不同的内存地址,为使每个对象在内存中的地址不同,所以在类中会加入一个隐含的字节

     

    默认构造函数

    默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。默认构造函数可能是这样,比如:

    Stock::Stock() {}

    默认构造函数没有参数,因为声明中不包含值

    当且仅当没有定义任何构造函数时,编译器才提供默认构造函数,为类定义了构造函数后,程序员就必须为它提供默认构造函数。如果提供了非默认构造函数,而没有提供默认构造函数,则下面的声明会出错:

    Stock stock1;

    这样做的原因可能是想禁止创建未初始化的对象,然而,如果要创建对象,而不是显式地初始化,则必须定义一个不接受任何参数的默认构造函数。定义默认构造函数的方式有两种。一种是给已有的构造函数的所有参数提供默认值:

    Stock(const string &co = "Error",int n = 0,double pr = 0.0);

    另一种方式是通过函数重载来定义另一个构造函数--一个没有参数的构造函数:

    Stock();

    由于只能有一个默认构造函数,因此不要同时采用这两种方式。

    在设计类时,通常应提供对所有类成员做隐式初始化的默认构造函数

    如:

     

    Stock::Stock()
    {
        company = "no name";
        shares = 0;
        share_val = 0.0;
        total_val = 0.0;
    }

     

    析构函数

    析构函数完成清理工作,如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存

    析构函数的调用:

    • 如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用
    • 如果创建的是自动存储类对象,则其析构函数将在程序执行完代码块时自动被调用
    • 如果对象是通过new来创建的,则它将驻留在栈内存或自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用

    例子:

    Stock stock1("abc",12,20.0);

    创建一个名为stock1的对象,并将其数据成员初始化为指定的值

    下面的语句使用另一种语法创建并初始化一个名为stock2的对象:

     

    Stock stock2 = Stock("Boffo",2,2.0)

     

    这种方法可能创建临时对象,也可能不创建临时对象

    另一种方式是创建一个临时对象,然后将临时对象赋值到stock2中,并丢弃它,如果编译器使用的是这种方式,则将为临时对象调用析构函数

     

    Stock st1("Nanosmart",12,20.0);
    Stock st2 = Stock("Bob",2,2.0);
    st1 = Stock("Niffy",10,50.0);//将创建临时对象,并复制给st1

    析构函数的调用顺序是按声明顺序的栈序列进行的,即先声明的对象,后析构

    C++11列表初始化

    C++11中,可将列表初始化语法用于类,只要提供与某个构造函数的参数列表匹配的内容,并用大括号将它们括起:

    Stock hot_tip = {"Derivatives Plus Plus",100,45.0};
    Stock jock {"Sport Age Storage,Inc"};
    Stock temp {};

    在前两个声明中,用大括号括起来的列表与下面的构造函数匹配:

    Stock::Stock(const std::string &co, long n = 0, double pr = 0.0);

     const成员函数

    const Stock land = {"Kludgehorn Properties"};
    land.show();

    对于C++来说,编译器将拒绝第二行,因为show()的代码无法确保调用对象不被修改

    需要一种新的语法,保证函数不会修改调用对象。C++的解决方法是将const关键字放在函数的括号后面,如

    void show() const;

    函数定义的开头应该这样:

    void stock::show() const

    以这种方式声明和定义的类函数被称为const成员函数(防止方法调用修改对象)

    对象数组

    用户通常要创建同一个类的多个对象,可以创建独立对象变量,也可以创建对象数组:

    Stock mystuff[4];

    当程序创建未被显式初始化的类对象时,总是调用默认构造函数,可以用构造函数来初始化数组元素,这种情况下,必须为每个元素调用构造函数:

    const int STKS = 4;
    Stock stock[STKS] = {
        Stock("NanoSmart",12.5,20),
        Stock("Boffo Objects",200,2.0),
        Stock("Monolithic Obelisks",130,3.25),
        Stock("Fleep Enterprises",60,6.5)
    };

    这里的代码使用标准格式对数组进行初始化:用括号括起来的、以逗号分隔的值列表,括号里面的每个对象都是临时对象,然后将值复制给数组元素

    初始化对象数组的方案是

    1. 首先使用默认构造函数创建数组元素
    2. 然后花括号中的构造函数将创建临时对象
    3. 然后将临时对象的内容复制到相应的元素中

    因此,要创建类对象数组,则这个类必须有默认构造函数

    作用域为类的常量

    有时候,使符号常量的作用域为类很有用,因此创建一个由所有对象共享的常量是个不错的主意

    class Bakery
    {
        private:
            const int Months = 12;
            double costs[Months];
            ...
    }

    但这样是行不通的,因为声明类只是描述了对象的形式,并没有创建对象,因此在创建对象前并没有用于存储值得空间

    第一种方式是在类中声明一个枚举,在类声明中声明的枚举的作用域为整个类,因此可以用枚举为整型常量提供作用域为整个类的符号名称,如

    class Bakery
    {
        private:
            enum {Months = 12;};
            double costs[Months];
            ...
    }

    用这种方式声明枚举不会创建类数据成员,也就是说,所有对象中都不包含枚举,Months只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用12来代替它

    C++提供了另一种在类中定义常量的方式--使用关键字static:

    class Bakery
    {
        private:
            static const int Months = 12;
            double costs[Months];
            ...
    }

    这将创建一个名为Months的常量,该常量与其他静态变量存储在一起,而不是存储在对象中,因此,只有一个Months常量,被所有Bakery对象共享

  • 相关阅读:
    xml=>数组
    php的session锁
    压缩服务器中的文件夹,并下载到电脑
    通过onkeydown事件来控制只允许数字
    简单算法
    memcahe安装
    HTML div css 强制 换行 不换行
    windows charles response 乱码解决办法
    根据字节流判断内容是否使用UTF-8编码
    nginx安装过程
  • 原文地址:https://www.cnblogs.com/jiweilearn/p/10679803.html
Copyright © 2020-2023  润新知