C++学习-Day-20

一、抽象和类

生活中充满了复杂性,处理复杂性的方法之一是简化和抽象。在计算机中,为了根据信息与用户之间的接口来表示它,抽象是至关重要的。也就是说要将本质特征抽象出来,并根据特征来描述解决方案。在C++中,用户定义类型是指实现抽象接口的类设计。

类型是什么?我们制定基本类型主要完成了三项工作:

  1. 决定数据对象需要的内存数量;
  2. 决定了如何解释内存中的位(long和float在内存中所占的位数相同,但是将它们转换为数值的方法不同);
  3. 决定了使用数据对象执行的操作或方法。

C++中的类。类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组成合成一个整洁的包。首先我们要先考虑如何表示一个类;接着我们来定义类,一般来说类规范由两个部分组成,即类声明和类方法定义。类声明:以数据成员的方式描述数据部分,以成员函数(方法)的方式来描述公有接口。类方法定义:描述如何实现类成员函数。简单来说,类声明提供了类的蓝图,而方法提供了细节。

什么是接口?接口是一个共享框架,供两个系统交互时使用。对于类,我们说公共接口。这里公众是使用类的程序,交互式系统由类对象组成,而接口有编写类的人提供的方法组成。我们要使用某一个类对象,无需直接访问类成员,只需使用该类的方法即可。类设计禁止公共用户直接访问类。

为开发一个类并编写一个使用它的程序,需要完成多个步骤。这里将开发分成多个阶段,通常c++程序员将接口(类定义)放在头文件中,并将实现(类方法)放在源代码文件中。

class Student{
    //成员变量
	private:
    char *name;
    int age;
    float score;
 	public:
    //成员函数
    void say(){
    printf("%s的年龄是 %d,成绩是 %f\n", name, age, score);
    }
    };

其中private和public关键字描述了对类成员的访问控制,private的成员公共用户需要使用public的函数来调用。

类设计尽可能将公有接口与实现分开。公有接口表示设计的抽象组件,将实现细节挡在一起并将它们与抽象分开被称为封装。数据隐藏(将数据放在类的私有部分)是一种封装。

实现类成员函数。成员函数定义和常规函数定义非常相似,都有函数头和函数体。但是类成员函数还有两个特殊的特征:

  1. 定义成员函数时,使用作用域解析运算符(::)来指定函数所属的类;
  2. 类方法可以访问类的private组件。

比如我们可以定义一个类成员函数update()的函数头为void Stock::update(double price);
这样我们不仅描述了函数所属的类,也告诉我们可以在其他类中也定义相同函数名的成员函数。因此,作用域解析运算符确定了方法定义的类的身份,同时方法可以访问类的私有成员。

实现类成员函数,我们可以在类声明中提供完整的函数定义(函数实现较小的情况),此时函数将自动成为内联函数。我们也可以在声明之外定义成员函数并使之成为内联函数,只需在类实现之中定义函数时使用inline限定符即可。

二、类的构造函数和析构函数

C++的目标之一是让使用类对象就像使用标准类型一样,常规的初始化语法不适用于类,因为数据部分是私有的,不能直接访问,因此需要设计合适的成员函数才能将对象初始化,一般最好是在创建对象时进行初始化。为此,C++提供了一个特殊的成员函数—类构造函数,专门用于构造新对象、将值赋给它们的数据成员。

声明和定义构造函数。声明构造函数和常规函数类似,不过没有声明类型,函数名与类名相同。例如:
Stock(const string &co, long n=0, double pr=0.0);
注意在声明构造函数时,不要将类成员名用作构造函数的参数。

使用构造函数。C++提供了两种使用构造函数来初始化对象的方式,第一种是显式地调用构造函数:Stock food=Stock(“world”,250,1.25);
另一种是隐式地调用构造函数:Stock garment(“world”,250,1.25);
每次创建类对象(甚至使用new动态分配内存)时,C++都使用类构造函数。下面是将构造函数与new一起使用的方法:Stock *pstock=new Stock(“games”,18,19.0);

对象是无法用来调用构造函数的,因为在构造函数创建对象之前对象是不存在,因此构造函数被用来创建对象。

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

析构函数。用构造函数创建对象后,程序负责跟踪该对象,直到过期为止。对象过期时,程序将自动调用一个特殊的函数—析构函数,该函数完成清理工作。例如构造函数使用new来分配内存,则析构函数将使用delete来释放内存,当构造函数没有使用new时,析构函数什么都不用做。析构函数的声明很特殊,在类名前加上~,可以没有返回值和声明类型,与构造函数不同的是析构函数没有参数。

const成员函数。为了保证类函数成员在调用时不会被修改,需要一种新的语法,C++的解决方法是将const关键字放在函数括号的后面。

三、this指针

有时候方法调用会涉及到多个对象,在这种情况下我们需要使用this指针。每个成员函数(包括构造函数和析构函数)都有一个this指针,其指向调用对象。

四、对象数组

用户通常要创建同一个类的多个对象,我们可以创建多个独立的对象变量,但是创建对象数组将更好。创建对象数组和创建标准类型的数组相同。初始化对象数组的方案是首先使用默认构造函数创建数组,然后非默认构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中去。因此要创建对象数组,则这个类必须有默认构造函数。

五、类作用域

在类中定义的名称的作用域为整个类,且它们在类中是已知的,在类外是不可知的,因此可以在不同的类中使用相同的类成员名。在类声明或成员函数定义中,可以使用未修饰的成员名称,构造函数名称在被调用时才能被识别,因为它与类名相同。在其他情况下使用类成员名时必须根据上下文使用直接成员运算符、间接成员运算符或作用域解析运算符。

作用域为类的常量。有时候使用作用域为类的常量很有用,我们有两种方法实现这个目标,第一个是使用枚举;另一种是在类中定义常量—使用关键字static。

六、抽象数据类型

程序员常常通过定义类来表示更通用的概念。例如就实现计算机专家们所说的抽象数据类型而言,使用类是一种非常好的选择。使用栈就是这样一种应用,栈由可对它执行的操作来描述:

  1. 可创建空栈
  2. 可将数据项压入
  3. 可从栈顶删除数据
  4. 可查看栈是否填满
  5. 可查看栈是否为空
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值