类的三大特性

  • 封装性:将紧密相关的数据和方法组合成类,并对类中的成员访问进行限制,防止外界对类内部的破坏。
  • 继承性:经过不同程度的抽象,将分散的各种类联系起来,从而建立起一个相互联系的系统。当系统中添加新类时,不用从头开始写程序,只需要从已有的系统中选取相应的基类,继承它,然后添加新的功能即可。
  • 多态性:类定义一个接口可以有不同的实现,只有在类运行时才确定使用哪个实现。

类的定义

class 类名
{
private:                        //私有
    私有数据成员和成员函数;
protected:                      //保护
    保护数据成员和成员函数;
public:                         //公有
    公有数据成员和成员函数;
}

一个类中的成员函数可以不受限制的访问该类的数据成员,而该类以外的类访问该类的数据成员和成员函数会受到限制,这体现了类的封装性

定义在类体内的成员函数叫内联函数。定义在类外的成员函数叫外联函数。我们可以通过关键字  inline 将外联函数转换成内联函数(其外联转内联的过程在编译中进行)。

(一)
class student
{
private:
    char name[9];
public:
    void showname();
};

void student::showname()        //外联函数
{
    cout << name;
}


(二)
class student
{
private:
    char name[9];
public:
    void showname()            //内联函数
    {
        cout << name;
    }
};


(三)编译时外联转内联
class student
{
private:
    char name[9];
public:
    void inline showname();    //编译时外联转内联
};

void student::showname()
{
    cout << name;
}

在使用内联函数时应该注意:

  • 内联函数体内不能有循环语句和 switch 语句。
  • 内联函数必须在第一次被调用之前定义。

数据成员

为了体现面向对象程序设计信息的隐蔽性,数据成员均被定义为私有成员。并且在定义是应该注意一下两点:

  • 数据成员不能在定义时对其进行初始化,其初始化是在具体对象创建后由构造函数完成的。
  • 数据成员不能进行递归定义,即不能使用自身类的对象作为该类的数据成员。
class A
{
private:
    int i = 1;    //错误

    A i;          //错误
    
    int i;        //正确
}

成员函数

成员函数一般格式为:

类型 类名::函数名(参数)
{
    函数体;
}

“::” 为作用域运算符,用于声明成员函数所从属的类。

成员函数向类的外部给出了提供服务的接口,该接口是对封装数据成员进行操作的唯一途径。

成员函数调用方式如下:

int add_init(int x=6,int y=30)
{
    return(x+y);
}


add_init(10,20);    //用实参来初始化形参,实现10 + 20
add_init(10);       //形参x采用实参值10,y采用默认值30,实现10 + 30
add_init();         //x y 都使用默认值,实现 6 + 30

访问权限

类成员从访问权限上分:公有(public)、私有(private)、保护(protected)。默认为 private 。

  • 公有(public):任何代码都可以访问。
  • 私有(private):只能被自身成员函数及友元函数访问。
  • 保护(protected):可以被自身成员函数、友元函数和派生类成员访问。

构造函数

  • 是成员函数,其说明在类体内。其函数体可写在体内也可写在体外。
  • 名字和类名相同,定义和说明构造函数时,不必指明函数的类型。
  • 用于创建对象时系统自动调用,也可在函数中调用构造函数创建无名对象。
  • 可以由一个或多个参数,也可以没有参数。
  • 可以重载。
  • 在类的定义中没有给出构造函数,则系统会自动创建一个默认的构造函数,默认构造函数不起任何作用,没有参数。在创建对象时,将数据成员初始化为0。
  • 不能被继承,不能说明为虚函数,不能被显示调用,不能对构造函数进行取地址操作。
  • 是公有成员函数。
class A
{
public:
    A()
    {
        cout<<"AAA\n";
    }
};

class B
{
public:
    B()
    {
        cout<<"BBB\n";
    }
};

class C
{
public:
    C()
    {
        cout<<"CCC\n";
        num = 0;
    }
protected:
    A a;
    B b;
    int num;
};

void main()
{
    C c;
    cout<<"back into main.\n";
}

输出:
AAA
BBB
CCC
back into main.

主程序运行,当遇到创建C类的对象时,就调用构造函数C()。该构造函数运行时,首先分配空间,包含一个A对象,一个B对象,一个int型数据,然后在类声明的对象成员依次调用其构造函数。

析构函数

  • 是成员函数,其说明在类体内。其函数体可写在体内也可写在体外。
  • 名字和类名相同,在析构函数前加“~”,表明功能与构造函数相反。
  • 它可以被自动调用,也可以被系统调用。
  • 通常利用析构函数删除对象中由指针成员所指向的动态分配到存储空间,当类中不使用动态存储空间时,通常不需要定义析构函数。

析构函数的调用方式:

  • 一个对象当其结束生命周期时,例如一个函数体内定义的对象,当该函数结束时,自动调用析构函数释放该对象。
  • 使用new运算符创建的对象,在使用delete运算符释放该对象时,系统自动调用析构函数。
  • 当变量超过作用域时,析构函数被隐式调用。
  • 当指向对象的指针超过作用域时,析构函数不能被隐式调用:如果要删除对象时,必须使用delete操作符。
  • 对于全局变量,在主函数main()终止时,自动调用析构函数。
  • 对于局部变量,当函数结束时,自动调用析构函数。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章