第10章 对象和类(P341-377)

过程性编程和面向对象编程

过程性编程:首先考虑要遵守的步骤,然后考虑如何表示这些数据
OOP方法:首先从用户角度考虑对象—描述对象所需的数据以及描述用户与数据交互所需要的操作。完成对接口的描述后,需要确定如何实现接口和数据存储,最后,使用新的设计方案创建出程序。

类的定义一般放在头文件里,使用class关键字定义,并且类名称第一个大写:

# student.h
#include<string>
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
	std::string name;
	double scores;
	int age;
public:

	void show();
	
};
#endif

void Student::show() {
	std::cout << "the student name is:" << name << std::endl;
	std::cout << "the student age is:" << age << std::endl;
	std::cout << "the student scores is:" << scores << std::endl;
}

下来详细解释这段代码。#ifndef…#endef,之前介绍过,就不多说了。类中一共分为两部分,一部分private(私有),另一部分pubilc(共有)。私有表示该里边的变量时私有的,不允许外部访问,而共有部分可以直接访问,所以只能通过共有部分的函数去访问私有变量,这体现了类的封装性,以及对数据的保护。
其次,一般函数都会放在共有部分,称之为成员函数。成员函数的原型都会放在类中,如示例中的void show。函数的定义放在文件中,定义时,函数前面使用作用域解析运算符来表示函数所属的类:Student::show()。但是,可以将函数的定义也放在类声明中,这样定义的函数将会变成内联函数,因此,可以将一些短小的函数定义放在类声明中,变成内联函数。最后,使用成员函数,与结构相同,通过成员运算符。如,stu1时已经声明的成员对象:stu1.show()。

构造函数与析构函数

虽然现在我们可以像初始化int或者结构那样初始化类对象,而只能通过成员函数给变量赋值,为此,c++提供一种特殊的函数-----构造函数,专门用于构造新对象,将值赋给他们的数据结构。构造函数的名称与类名相同,并且,构造函数的原型和函数头有一个有趣的特征----虽然没有返回值,但没有被声明为void类型,实际上,构造函数没有声明类型。
与成员函数相同,构造函数原型在类的共有部分,定义在文件中。

#pragma once
#include<string>
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
	std::string name;
	double scores;
	int age;
public:
	Student(const std::string  , double , int );
	void show();
	
};
#endif
# class.cpp
Student::Student(const std::string  na, double sc, int ag) {
	name = na;
	scores = sc;
	age = ag;
}

c++提供了两种使用构造函数来初始化对象的方式:

Student stu1 = Studnet("kyle", 85.6, 18);

Student stu2 ("smith", 60.5, 19);

第一种时显式的调用构造函数,第二种是隐式的调用构造函数,这样格式更紧凑。

默认构造函数:在未提供显式初始值时,用来创建对象的构造函数,如果没有提供任何的构造函数,c++将自动提供默认的构造函数,这样不能初始化其成员,默认构造函数中没有参数

Studnet::Student(){  }

这是定义默认构造函数的方法之一,另一种是给已有的构造函数的所有参数提供默认值。但默认构造函数只能有一个,因此两种方法二选一。

析构函数:用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止,对象过期时,程序将自动调用一个特殊的成员函数----析构函数。析构函数完成清理工作,例如在构造函数使用new分配空间,那么析构函数中就要使用delete清理空间。析构函数名称也很特殊,类名前加~,与构造函数不同的是,析构函数没有参数,其原型:

~Student();

定于方式与其他成员函数相同。

下面是一个综合的示范:

//student.h
#pragma once
#include<string>
#ifndef _STUDENT_H_
#define _STUDENT_H_
class Student {
private:
	std::string name;
	double scores;
	int age;
public:
	Student();  //默认构造函数
	Student(const std::string  , double , int );  //传递三个变量
	Student(const std::string &);  //传递一个变量
	void show();
	~Student();  //析构函数
};


#endif
// class.cpp
#include<iostream>
#include"student.h"


Student::Student(const std::string  na, double sc, int ag) {
	name = na;
	scores = sc;
	age = ag;
}

Student::Student()
{
	name = "None";
	scores = 0.0;
	age = 0;
}

Student::Student(const std::string  &na) {
	name = na;
	age = 0;
	scores = 0.0;
}

void Student::show() {
	std::cout << "the student name is:" << name << std::endl;
	std::cout << "the student age is:" << age << std::endl;
	std::cout << "the student scores is:" << scores << std::endl;
}

Student::~Student() {
	std::cout << "bee " << name << " ! "<<std::endl;
}
//index.cpp
#include<iostream>
#include"student.h"
int main() {
	Student stu1;
	Student stu2("kyle", 80.1, 17);
	Student stu3("smith");
	stu1.show();
	std::cout << "-------------------------" << std::endl;
	stu2.show();
	std::cout << "-----------------------------" << std::endl;
	stu3.show();
	std::cout << "-----------------------------" << std::endl;
	return 0;
}

最终结果

this指针

现在新声明一个成员函数,比较两个对象的分数,并返回分数高的对象。需使用a对象的该成员函数,参数是b对象。或者使用b对象的该成员函数,参数时a对象,然后比较分数,比如调用的是a对象的成员函数,且a分数高于b,即要返回a对象,那么return谁呢?这里就有一点问题了,因此c++提供了this指针,在成员函数中,this指向本对象,谁调用的成员函数,就指向谁。

上述实例中,某个成员函数中
scores 与this->scores是等价的

因此,要返回该对象,使用 *this即可:

//class.cpp中函数定义
const Student & Student::max_(const Student& t) const {
	if (this->scores > t.scores)
		return *this;
	else
		return t;
}

这里需要注意,Student表示返回值为Student 引用,即返回本身,不会返回副本,提高效率,名称中最后的const表示this指针不会修改西私有变量,这一点需要注意:
在这里插入图片描述

对象数组

如果有多个对象,可以利用对象数组:

Student stu[5]{
	Student(...),
	Student(...),
	Student(...),
	Student(...),
	Student(...)
};

使用方法与正常数组方法相同。
最后一点,在类中定义常量:

class Student{
private:
	const int SIZE = 5;
	...
}

本意是定义一个常量,但是行不通的,声明类只是描述了声明对象的形式,并没有创建对象。所以在定义对象前,没有内存空间,无法定义常量。
有另外两种方式:
1.利用枚举类型:

class Student{
private:
	enum {Months = 5}
	...
}

2.利用static声明静态变量:

class Student{
private:
	static const int SIZE = 5;
	...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值