• 《现代c++程序设计》(美)Barbara Johnston----2:类和对象


    “这项工作有谁来完成”这个问题对于设计类和使用对象来说非常重要。

    在编写程序之前,很重要的一步就是问问自己需要哪些类,每个类分别完成什么功能。

    如下是一些以前使用过的类:

    string        处理文本数据

    vector       数据列表

    queue        队列,先入先出

    ifstream     打开数据文件并读取文件

    ofstream     打开数据文件并写入文件

    要使用这些类,需要在程序文件的开头包含对应的库文件,然后就可以创建对象来完成特定的工作。

    对象后面跟一个点运算符的方式来访问类中的定义功能

    编写自己的类

    类的定义格式:

    通常,会在public部分定义类的行为,提供公共的函数接口供外部访问;在protected部分,定义遗传特性;在private部分,定义这个类私有的属性和行为。
    与类成员的访问控制类似,派生方式也有三种:public派生,所有全部继承,不做改变,如Teacher类从Human类中派生;private派生,把基类的所有公有(public)成员都变成自己私有的,这样派生类不在直接支持基类的公有接口,它只希望可以重用基类的实现而已;protected派生,把基类的所有公有(public)成员都变成protected类型,保护基类的所有接口不被外界访问,只能由自身及自身的派生类访问。

    c++程序都遵循这样一个惯例:将类的声明保存在于类名称相同的头文件(*.h)中,而类成员函数的实现代码保存在同名的*,cpp中,例如Data.cpp。

    因此,一个类的代码往往保存在一对文件中,例如Date.h和Date.cpp。这样可以方便代码的复用,只要把一个类的两个文件加入到工程中就可以使用了。参见C++中的头文件和源文件

    具体例子:

    整个程序包含一个头文件.h,和2个.cpp源文件,如下

    代码:

    .h文件,负责类的声明

    #pragma once        //防止一个 头文件被多次编译
    #include<string>
    using namespace std;
    
    class VolumeCalc
    {
    private:
        double sphRadius;
        double boxLength, boxWidth, boxHeight;
        double sphVolume, boxVolume;
    
        void CalcBoxVol();//被set函数调用
        void CalcSphVol();
    
    
    public:
        VolumeCalc();            //类的构造函数,创建对象时,会自动调用的成员函数
        
        void SetSphRadius(double r);
        void SetBoxDim(double l, double w, double h);//set函数总是负责把数据传入到类中,get函数负责从类中取出数据
    
        double GetSphVol() { return sphVolume; }
        double GetBoxVol() { return boxVolume; }//函数简单的话直接在里面定义了就
    
    
    
    };

    同名的.cpp负责函数 的实现,

    //包含volume cal类 的一些函数定义
    
    #include"VolumeCalc.h"
    #include<cmath>
    using namespace std;
    
    VolumeCalc::VolumeCalc()               //构造函数
    {
        boxHeight = boxWidth = boxLength = 0.0;
        sphRadius = 0.0;
        boxVolume = sphVolume = 0.0;
    }
    
    //set函数在收到新数据之后就调用calcula函数
    
    void VolumeCalc::SetSphRadius(double r)
    {
        sphRadius = r;
        CalcSphVol();
    }
    
    
    void VolumeCalc::SetBoxDim(double l, double w, double h)
    {
        boxLength = l;
        boxWidth = w;
        boxHeight = h;
        CalcBoxVol();
    }
    
    
    void VolumeCalc::CalcBoxVol()
    {
        boxVolume = boxHeight*boxLength*boxWidth;
    }
    
    void VolumeCalc::CalcSphVol()
    {
        double PI = 3.14159265;
        sphVolume = 4.0 / 3.0*PI*pow(sphRadius, 2);
    }

     另一个为主函数:

    #include<iostream>
    #include"VolumeCalc.h"
    //#include<cmath> .h头文件已经包含,可以略去
    
    using namespace std;
    
    int main()
    {
        cout << "calculation volume of a"
            << " box or a sphere" << endl;
        VolumeCalc Bob;         //创建对象,让BOb替我们来完成计算
    
        //使用局部变量len,wid等来保存用户输入的数据
        double len, wid, hgt;
        double rad;
        cout << "Box : ENTER the length width and geight 
    ";
        cin >> len >> wid >> hgt;
        cout << "Box : ENTER the radius 
    ";
        cin >> rad;
    
        Bob.SetBoxDim(len, wid, hgt);
    
        Bob.SetSphRadius(rad);//set函数总是负责把数据传入到类中,get函数负责从类中取出数据
    
        //其实。类不过是扩展我们可以使用的数据类型,也不用想的有多么难
        //现在,让Bob告诉我们计算的数据结果,
        //调用对象的get函数
        double sphereV = Bob.GetSphVol();
        double boxV = Bob.GetBoxVol();
    
        cout.setf(ios::fixed);
        cout.precision(3);
    
        cout << "
     box volume :" << boxV
            << "
     sphere volume :" << sphereV;
    
    
    
        cin.get();
        cin.get();
        return 0;
    
    }

    关于析构函数:

    new关键字创建一个指向对象 的指针,

                     //创建一个新的对象,并让pMrChen指针指向这个新的对象

                    Teacher* pMrChen = new Teacher();   //之前已经定义了Teacher类

    这里,使用“new”关键字创建了一个Teacher类的对象,“new”关键字会调用Teacher类的构造函数来 完成对象的创建,并返回这个对象 的地址,再将这个返回的对象地址赋值给pMrChen指针,这样就同时完成了对象 的创建和指针的赋值。

    有了指向对象的指针,就可以利用“-->”运算符,通过指针访问该对象 的成员。

    要特别注意的是,跟普通的变量不同,使用new关键字创建的对象无法在结束其生命周期的时候自动销毁,所以必须使用“delete”关键字销毁这个对象,释放其占用的内存。

    如:   delete pMrChen;

    "delete"首先会调用Teacher类的析构函数~Teacher()完成这个对象特有的清理工作,然后释放掉这个对象占有的内存,整个对象也就销毁了。

  • 相关阅读:
    Nginx进程信号管理
    Nginx配置缓存服务器
    访问Nginx显示目录
    kubeadm快速安装k8s
    《构建之法》读书笔记(一)
    Android Studio连接SQLite数据库与SQLite Studio实时同步的实现
    关于sqlite数据库与sqlite studio
    AS之去掉顶部标题栏
    今日学习
    AS之AlertDialog使用
  • 原文地址:https://www.cnblogs.com/skylover/p/7252782.html
Copyright © 2020-2023  润新知