首页 > 编程笔记 > C++笔记 阅读:30

C++类的定义和使用(非常详细,附带实例)

C++ 中的类可以是对同一类型事物进行抽象处理后的结果,也可以是一个层次结构中的不同层次节点。

例如,将客观世界看成一个 Object 类,动物是客观世界的一部分,定义为 Animal 类;狗是一种哺乳动物,是动物类的子类,定义为 Dog 类;鱼也是一种动物,定义为 Fish 类。

上述各类之间的层次关系如下图所示:


图 1 类的层次关系

类是一种新的数据类型,它和结构体有些相似,是由不同数据类型组成的集合体。不同的是,类比结构体增加了操作数据的行为,这个行为就是成员函数。

C++类的声明与定义

类在使用前,需要先进行声明和定义。C++ 中,使用 class 关键字定义一个类。类的定义格式如下:
class 类名标识符
{
    [public]
    [成员变量的声明]
    [成员函数的声明]
    [private]
    [成员变量的声明]
    [成员函数的声明]
    [protected:]
    [成员变量的声明]
    [成员函数的声明]
};
大括号内被称为类体或类空间,是定义和声明类成员的地方。关键字 public、private、protected 是类成员访问修饰符,限定了类成员的访问权限。大括号后要有分号。

类成员包括两类,分别是成员变量和成员函数:
注意,其他类的对象可以作为类的成员,自身类的对象不可以作为类的成员,但自身类的指针或引用可以作为类的成员。

例如,下面给出一个员工信息类的定义:
class CPerson //定义 CPerson 类
{
    //声明 4 个成员变量
    int m_index;  //声明 m_index,表示员工编号
    char m_cName[25];  //声明 m_cName[25],表示员工姓名
    short m_shAge;  //声明 m_shAge,表示员工工龄
    double m_dSalary;  //声明 m_dSalary,表示员工薪资

    //声明 8 个成员函数
    short getAge();  //声明 getAge(),表示获取员工工龄
    int setAge(short sAge) //声明 setAge(),设置员工工龄
    int getIndex();  //声明 getIndex(),表示获取员工编号
    int setIndex(int index);  //声明 setIndex(),表示设置员工编号
    char *getName();  //声明 getName(),表示获取员工姓名
    int setName(char cName[25]);  //声明 setName(),表示设置员工姓名
    double getSalary();  //声明 getSalary(),表示获取员工薪资
    int setSalary(double dSalary);  //声明 setSalary(),表示设置员工薪资
};
上面的代码中,CPerson 是定义的员工信息类,大括号中包含了 4 个成员变量,分别表示 CPerson 类的 4 个属性;还包含 8 个成员函数,表示 CPerson 类的 8 种行为。

C++类的实现

CPerson 类中声明了类的成员,下面介绍如何定义类中的方法(即成员函数)。

1) 将类的成员函数都定义在类体内。例如,以下代码都在 Person.h 头文件内,类的成员函数都定义在类体内。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class CPerson //定义 CPerson 类
{
public:
    int m_index;
    char m_cName[25];
    short m_shAge;
    double m_dSalary;

    short getAge()  //定义 getAge(),表示获取员工工龄
    {
        return m_shAge;
    }
    int setAge(short sAge)  //定义 setAge(),表示设置员工工龄
    {
        m_shAge=sAge;
        return 0;
    }
    int getIndex()  //定义 getIndex(),表示获取员工编号
    {
        return m_index;
    }
    int setIndex(int index)  //定义 setIndex(),表示设置员工编号
    {
        m_index=index;
        return 0;
    }
    char *getName()  //定义 getName(),表示获取员工姓名
    {
        return m_cName;
    }
    int setName(char cName[25])  //定义 setName(),表示设置员工姓名
    {
        strcpy(m_cName,cName);
        return 0;
    }
    double getSalary()  //定义 getSalary(),表示获取员工薪资
    {
        return m_dSalary;
    }
    int setSalary(double dSalary)  //定义 setSalary(),表示设置员工薪资
    {
        m_dSalary=dSalary;
        return 0;
    }
};

2) 将类体内成员函数的实现放在类体外,此时需要使用域限定符“::”标识该方法属于哪个类。放在类体内和类体外定义的效果是一样的。
class CPerson //定义 CPerson 类,声明 4 个成员变量和 8 个成员函数
{
public:
    int m_index;
    char m_cName[25];
    short m_shAge;
    double m_dSalary;

    short getAge();
    int setAge(short sAge);
    // 省略其他成员函数的声明代码
};

// CPerson 类成员函数的实现部分
short CPerson::getAge()  //定义 getAge(),在类体外定义要使用域限定符“::”
{
    return m_shAge;
}
int CPerson::setAge(short sAge)  //定义 setAge(),在类体外定义要使用域限定符“::”
{
    m_shAge=sAge;
    return 0;
}
// 省略其他成员函数的实现代码

除此以外,C++ 中还可以将函数的声明和定义放在不同的文件内。一般在头文件中放入函数的声明部分,在实现文件中放入成员函数的实现部分。同样,也可以将类的定义放在头文件中,将类的成员函数的实现放在实现文件内。存放类的头文件和实现文件最好和类名相同或相似。

例如,将 CPerson 类的声明部分放在 Person.h 文件内,程序代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class CPerson  //定义 CPerson 类,声明 4 个成员变量和 8 个成员函数
{
public:
    int m_index;
    char m_cName[25];
    short m_shAge;
    double m_dSalary;

    short getAge();
    int setAge(short sAge);
    int getIndex();
    int setIndex(int index);
    char *getName();
    int setName(char cName[25]);
    double getSalary();
    int setSalary(double dSalary);
};

将 CPerson 类的实现部分放在 Person.cpp 文件内,程序代码如下:
#include "Person.h"  //CPerson 类成员函数的实现部分
short CPerson::getAge()
{
    return m_shAge;
}
int CPerson::setAge(short sAge)
{
    m_shAge=sAge;
    return 0;
}
//省略其他成员函数的实现代码
整个工程的所有文件如下图所示:


图 2 工程所有文件

注意,类的 .h 文件名不需要和 .cpp 文件名相同,但是在 .cpp 文件中包含头文件时,一定要和 .h 文件名一致。

关于类的实现,有以下两点说明:
1) 类的成员变量需要初始化,成员函数还需要添加实现代码。另外,类的成员变量不能在类的声明中初始化。例如,下面的代码将无法通过编译:
class CPerson
{
    int m_index=1;  //错误写法,不能在类的声明中初始化
    char m_cName[25]="Mary";  //错误写法,不能在类的声明中初始化
    short m_shAge=22;  //错误写法,不能在类的声明中初始化
    double m_dSalary=1700.00;  //错误写法,不能在类的声明中初始化

    short getAge();
    int setAge(short sAge);
    //省略其他成员函数的声明代码
};

2) 空类是 C++ 中最简单的类,通常用来占位。其声明方式如下:
class CPerson{};
程序开发中,空类表示此处暂不定义,后续根据需要再定义其类成员及方法实现。

C++对象的声明和引用

类是一种数据类型,用户定义类后,即可通过类名声明对象。语法格式如下:
类名 对象名

例如,使用前面定义的 CPerson 类声明对象:
CPerson p;  //声明对象 p
CPerson p1,p2,p3.  //声明 3 个对象 p1、p2、p3

对象的引用方式有两种:使用成员运算符“.”和使用指向运算符“->”。
1) 使用“.”运算符引用成员变量和成员函数,语法形式如下:
对象名.成员名
对象名.成员名(参数表)  //参数表
例如,可通过 p.m_index、p.getAge() 引用类 p 中的成员。

2) 对象数组、对象指针和引用形式的对象,需要使用指向运算符“->”运算符进行引用。例如,声明一个对象指针 p,使其指向对象 m_iIndex,代码如下:
CPerson *p;
p->m_iIndex;

下面两种引用成员变量的形式是等价的:
对象指针名->数据成员名
(*对象指针名).数据成员名

同样,下面两种引用成员函数的形式也是等价的:
对象指针名->成员函数名(参数表)
(*对象指针名).成员函数名(参数表)
例如,可通过 (*p).m_iIndex 或 p->m_iIndex 引用类 p 中的成员。

【实例】在本实例中,利用前文声明的 CPerson 类定义对象,然后使用该对象引用其成员。程序代码如下:
#include <iostream>
#include "Person.h"
using namespace std;
int main()
{
    int iResult=-1;
    CPerson p;  //声明对象 p,属于 CPerson 类
    iResult=p.setAge(25);  //引用 p.setAge(),设置工龄
    if(iResult>=0)
        cout << "m_shAge is:" << p.getAge() << endl;  //引用 p.setAge(),输出工龄

    iResult=p.setIndex(0);  //引用 p.setIndex(),设置员工编号
    if(iResult>=0)
        cout << "m_index is:" << p.getIndex() << endl;  //引用 p.getIndex(),输出员工编号

    char bufTemp[]="Mary";
    iResult=p.setName(bufTemp);  //引用 p.setName(),设置姓名
    if(iResult>=0)
        cout << "m_cName is:" << p.getName() << endl;  //引用 p.getName(),输出姓名

    iResult=p.setSalary(1700.25);  //引用 p.setSalary(),设置薪资
    if(iResult>=0)
        cout << "m_dSalary is:" << p.getSalary() << endl;  //引用 p.getSalary(),输出薪资
}
程序中首先使用 CPerson 类定义对象 p,然后引用类中的成员函数。p.setAge(25) 引用类中的 setAge() 成员函数,传递实参,设置员工工龄。函数返回值赋给 iResult 变量,并通过 iResult 判断函数 setAge() 为数据成员赋值是否成功,如果成功,使用 p.getAge() 得到赋值数据并显示输出。

之后使用对象 p 依次引用成员函数 setIndex()、setName()和setSalary(),然后通过对 iResult 变量的判断,决定是否引用成员函数 getIndex()、getName() 和 getSalary()。

相关文章