• 备忘:C++ 类 (初学之实录)。


    声明类的一般形式:

        class 类名 [:基类1[,基类2]]

        {

            private :

                私有的数据和成员函数;

            protected

                保护的数据和成员函数;

            public :

                公用的数据和成员函数;

        };

     

    private: 私有的。仅类内可见。子类及外部都不见。

    public: 公共的。类外也可见。

    protected: 受保护的。类及派生的子类可见。

     

    使用类时注意的小问题:

     

    使用类时,类在声明时,会直接创建类的实体。如果不想在声明时创建,一般使用指针方式声明类。如:

    1
    2
    3
    4
    5
    CTest A(x, y);  // 声明时直接创建了 A类,并执行A的构造函数 CTest(x, y);
    CTest *B; // 先声明一个类的指针    
    B = new CTest(x, y); // 在需要时,再创建类的实体。
    delete B; // 释放 B 的实体。如不执行delete释放。*B所指向的实体会一直存在。
    // 注意: A不用释放,他会在作用域结束时,自动释放,也就是函数执行完后。会自动释放A。

     

    构造函数

    1. 类的构造函数与类同名。

    2. 无参构造函数在类对象进入其作用域时调用构造函数。即类被创建时,调用构造函数。

    3. 构造函数没有返回值,因此也不需要在定义构造函数时声明类型,这是它和一般函数的一个重要的不同之点。

    4. 默认无参构造函数不需用户调用,也不能被用户调用。

    5. 在构造函数的函数体中不仅可以对数据成员赋初值,而且可以包含其他语句。但是一般不提倡在构造函数中加入与初始化无关的内容,以保持程序的清晰。

    6. 尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数,并非每个构造函数都被执行

    7. 如果用户自己没有定义构造函数,则C++系统会自动生成一个构造函数,只是这个构造函数的函数体是空的,也没有参数,不执行初始化操作。

    8. 派生类的构造函数不会继承父类的构造函数。需要显式执行。执行方法是在派生类的构造函数后加冒号:加父类的构造函数(可带参数)

      如:

    1
    2
    3
    4
    5
    6
    7
    class CTest1: CTest{
    public:
      CTest1(int x, int y):CTest(x) //CTest()是 CTest1的父类的构造函数, 假设其有参数。
    {
       ….. //语句。
    };
    }

     

     

    释构函数

    1. 类的释造函数与类同名,并在前面加上~

    2. 当类对象的生命期结束时,会自动执行析构函数。

    具体地说如果出现以下几种情况,程序就会执行析构函数:

    1. 如果在一个函数中定义了一个对象(它是自动局部对象),当这个函数被调用结束时,对象应该释放,在对象释放前自动执行析构函数。

    2. static局部对象在函数调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用static局部对象的析构函数。

    3. 如果定义了一个全局对象,则在程序的流程离开其作用域时(如main函数结束或调用exit函数) 时,调用该全局对象的析构函数。

    4. 如果用new运算符动态地建立了一个对象,当用delete运算符释放该对象时,先调用该对象的析构函数。

    5. 析构函数不返回任何值,没有函数类型,也没有函数参数。因此它不能被重载。一个类可以有多个构造函数,但只能有一个析构函数。

    6. 析构函数的作用并不是删除对象,而是在对象被册除(释放)时被调用的一个过程,以便在撤销对象占用的内存之前完成一些清理工作,使这部分内存可以被程序分配给新对象使用。

    7. 派生类是不能继承基类的析构函数的,也需要通过派生类的析构函数去调用基类的析构函数。

     

    构造与释构函数执行顺序:

     

    类在创建时:先依次执行上一父类的构造函数,再执行当前类构造函数。即类本身的构造函数是最后执行的。

    基类构造-->父1构造-->…….-->最近的父类构造-->本类(当前类)构造

     

    类在释放时:先执行本类释构函数。再依次执行父类的释构函数。如果有多层继承的,最后执行是最基类的释构。

    本类(当前类)释构-->最近的父类释构-->…….--> 父1释构-->基类构造

     

     

    类的函数成员的一些说明:

    static静态函数:

    在类的函数声明前加上 static关键字。即该函数就成了类的静态函数。他会在程序运行时,就为该函数声明内存。

    静态函数,是类本身的函数。直接用类名加作用域符::就可以调用,如: CTest::myFunc();

    不需在类的实创建后才能调用。这跟类的一般函数不同。他也可以在类的实体创建后,像使用一般函数一样使用,如 A.myFunc();

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class CTest
    {
    public:
        static void fn()
        {
            puts("TEST");
        }
        static void fn(int x) // 像普通函数一样, 虚函数可重载。
        {
            cout << "TEST:" << x << endl;
        }
    };
     
    void main()
    {
        CTest::fn(); // 直接引用静态函数
        CTest::fn(100);
     
        CTest A; // 类的实体
        A.fn(); // 实体引用静态函数
        A.fn(200);
    }

    调用父类虚函数

    调用父类的虚函数,在派生类作用域中可以用:this-><类名>::<函数名>();或 :: <类名>::<函数名>()在实体中可以用实例名加成员符 (.)或(->)<类名>::<函数名>

    如示例:

    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
    class CFather
    {
    public:
        virtual void Say() // 父类的虚拟函数
        {
            puts("father say");
        }
    };
     
    class CChild : public CFather
    {
    public:
        void Say() // 函数被重载
        {
            ::CFather::Say(); //也可写成 this->CFather::Say();
            puts("Child say");
        }
    };
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
        CChild C;
         
        C.Say();
        C.CFather::Say(); //实体引用父类虚函数
        system("pause");
    }

     

    纯虚函数

    纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式是

        virtual 函数类型 函数名 (参数表列) = 0;

    如:

    1
    2
    3
    4
    5
    6
    7
    class CTest
    {
    public:
        CTest(); // 构造函数
    protected:
        virtual float myFunc( )const =0;  //纯虚函数
    }

     

    纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统:“在这里声明一个虚函数,留待派生类中定义”。在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。纯虚函数只是了实现多态性。

    关于纯虚函数需要注意的几点:

      1. 纯虚函数没有函数体;

      2. 最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;

      3. 这是一个声明语句,最后应有分号。

  • 相关阅读:
    leetcode刷题
    剑指offer题解
    哈夫曼树和哈夫曼编码
    HashMap的扩容机制---resize()
    缓存穿透,缓存击穿,缓存雪崩解决方案分析
    字符串的排列组合问题
    乐观锁与悲观锁以及乐观锁的一种实现方式-CAS
    HTTP相关
    零散知识点
    Java大数相加
  • 原文地址:https://www.cnblogs.com/iSixth/p/4182576.html
Copyright © 2020-2023  润新知