CH4 - CL~2

更新时间:2023-09-24 04:58:01 阅读量: IT计算机 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

4.2类和对象

(3)类成员的访问控制:公有类型(public)、私有类型(private)和保护类型(protected)。 其中,protected主要用于类的继承(第7章)。 公有成员:可以被该类的所有对象访问。 私有成员:只能在类本身的方法内访问。

注意:一个类的所有成员(数据成员和成员函数)默认时均为私有,外部不能访问。

Exa1:查找下列代码中的错,说明原因并改正。

#include using namespace std; class Cat {

unsigned int itsAge; unsigned int itsWeight; void Meow();

int GetAge(); void SetAge (int age); };

int main() {

Cat Frisky;

Frisky.itsAge=6;

cout<

(4)类的成员函数

成员函数可以定义在类内部,也可以定义在类外部,定义在类内部的函数默认为inline(内联函数)。 一般,成员函数定义在类的外部,定义方法和一般函数定义方法非常相似,它们有函数头和函数体,也可以有返回类型和参数。但它们还有两个特殊的特征: ? 定义成员函数时,使用作用域操作符::来指明函数所属的类。 ? 类方法可以访问类的private组件。 例如:

class Cat // 开始声明一个Cat类 {

public: // 使成员函数公有 int GetAge(); void SetAge (int age); void Meow(); private: // 使成员变量私有,从类的成员函数内部访问私有成员变量 int itsAge; // 成员变量 };

void Cat::SetAge(int age) {

//访问私有成员变量itsAge itsAge = age; }

补充:作用域操作符::举例

std::cout<<“hello”<>n;

(5)带默认形参值得成员函数

调用函数时,没有给出实参,则使用默认形参值。

void Cat::SetAge(int age=5) {

// 通过参数age设置成员变量itsAge的值 itsAge = age; }

建议做的事:

? 设计类时,先想好该类包含哪些属性(哪些数据成员和成员函数) ? 给对象(变量)赋值而不是给类(类型)赋值。

int=5;//wrong int x;

x=5;//right

Cat.itsAge=5;//wrong Cat Frisky; //类似int x; Frisky.itsAge=5;//类似x=5;

? 必须将数据成员(成员变量)声明为私有。 ? 必须使用公有访问成员函数。

? 必须从类的成员函数内访问私有数据成员。

不该做的事:

不要试图在类的外部(使用类的程序)使用私有成员变量(数据成员)(exa1)。

练习1:阅读并调试P97:4.2.5程序实例,并和教案中的例子对比,理解类的概念。

关键概念: (1) 定义类

一般来说,类定义由两部分组成:

类声明:告诉编译器类包含的数据和功能(数据成员和成员函数),以及使用该类时所需要的存储空间大小。

实现类方法(类方法定义):描述类成员函数的功能,即如何实现类成员函数,是对类对象操作的接口。 (2) 控制对成员的访问:公有还是私有

隐藏数据是OOP主要的目标之一,因此数据项通常放在私有部分(作用域仅限于类内部,只有成员函数才能使用),组成类接口的成员函数放在公有部分(外部程序可以调用);否则,就无法从程序中调用这些函数。

数据成员一般是为成员函数服务的。

(3) 类的基本步骤:声明类,实现类的方法(函数定义,即表明具体功能),定义对象,访问对象成员(对

象操作)。或者理解为:定义类和使用类。

定义类:类声明和类方法实现。

使用类:定义对象,对象操作(通过点操作符访问对象成员)。

4.3 构造函数和析构函数

定义一个整型变量有两种方法。一种是先定义该变量,然后在程序中为其赋值。例如:

int n; n=7;

另一种方法是定义该变量并立即对其初始化。例如:

int n=7;

初始化把变量的定义和赋初值结合起来,构造函数即完成类似功能,即,定义对象时给对象的数据成员一个合适的初始值。

(1)构造函数是一个与类同名的类方法(成员函数);没有返回值;在创建对象时被自动调用;如果类中没

有显式给出,编译器会自动生成,但什么也不做。

(2)声明构造函数的同时,还需要声明一个析构函数。构造函数创建并初始化类的对象(被分配资源);析

构函数在对象被撤消后清除并释放所分配的内存(资源回收)。

(3)析构函数也必须与类同名,其前面有一个波浪号~。析构函数没有参数,没有返回值。因此,Cat类的

析构函数声明如下:

~Cat();

(4) 默认的构造函数和析构函数

所有对象都必须被构造和析构。如果你没有声明构造函数或析构函数,编译器回自动创建一个。构造函数可以无参,也可以有参,无参构造函数称为默认构造函数,你可以创建自己的默认函数。 (5) 构造函数重载

可以为一个类声明多个构造函数(函数名相同,函数重载),只要每个构造函数的形参表唯一即可。定义对象时,所使用的实参决定使用哪个构造函数。

Exa2:构造函数和析构函数测试

(1)

#include using namespace std; class Cat {

public:

Cat(){cout<<\,hello......\默认、内联构造函数 ~Cat(){cout<<\析构函数 private: int itsAge; };

int main() {

Cat Frisky; Cat Boots;

system(\ return 0; }

(2)

#include using namespace std; class Cat {

public:

Cat(){cout<<\,hello......\默认、内联构造函数 Cat(int n); //构造函数重载

~Cat(){cout<

int itsAge;

};

Cat::Cat(int n) {

itsAge=n;

cout<<\}

int main() {

Cat Frisky(6);// 实参决定使用哪个构造函数 Cat Boots(5); system(\ return 0; }

Exa3:使用构造函数和析构函数

#include

class Cat // Cat类声明 {

public: Cat(int initialAge); ~Cat(); int GetAge(); void SetAge(int age); void Meow(); private: int itsAge; };

// 构造函数,函数名和类名相同 Cat::Cat(int initialAge) {

itsAge = initialAge; }

// 析构函数,什么也不做。如果你声明一个构造函数,一定还要声明析构函数,即使什么也不做。它会使你的代码更清晰

Cat::~Cat() { }

// 定义GetAge类方法 int Cat::GetAge() { return itsAge; }

//定义SetAge类方法

void Cat::SetAge(int age) { itsAge = age; }

// 定义Meow()类方法 void Cat::Meow() { std::cout << \}

int main() { Cat Frisky(5); Frisky.Meow(); std::cout << \ std::cout << Frisky.GetAge() << \ Frisky.Meow(); Frisky.SetAge(7); std::cout << \ std::cout << Frisky.GetAge() << \ system(\ return 0; }

练习2:P105例4-3。

练习3:从下述抽象中选择一个(或自己定义的抽象),确定类中需要什么数据,并提供适当的构造函数集。解释你的决定:

(1) Book (2)Employee (3)Vehicle (4)Tree

本文来源:https://www.bwwdw.com/article/de0d.html

Top