C++ Prime Plus 第10章 对象和类

本文深入探讨C++面向对象编程(OOP)的核心概念,包括封装、多态、继承及抽象,详解类的组成、成员函数、构造与析构函数等关键机制。同时,介绍this指针的作用和对象数组的使用,以及类作用域的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ Prime Plus 第10章 对象和类

1. OOP特性

  1. 抽象
  2. 封装(将实现细节放在一起并将它们与抽象分开被称为封装,种类:1)数据隐藏 ;2)将类函数定义和类声明放在不同文件中)和数据隐藏(将数据封装到私有部分从而保护数据的完整性称为数据隐藏
  3. 多态
  4. 继承
  5. 代码的可重用性

2. 抽象和类

2.1 类的组成

  1. 类声明:数据成员描述数据部分+成员函数(方法)描述公有接口,一般放于头文件,类名首字母一般大写;
  2. 类方法定义:如何实现类成员函数,一般放于源文件

2.2 成员的访问控制

  1. 数据成员一般放在私有部分,成员函数一般放在公有部分;默认访问控制为private;
  2. 类和结构的区别:1)结构的默认访问控制是public,类是private;2)结构限制为只表示纯粹的数据对象;

2.3 成员函数

  1. 成员函数的定义:
    1)定义成员函数时,使用作用域解析运算符::来表示函数所属的类,也就是类作用域
    2)成员函数可以访问类的private部分;
  2. 内联函数:定义位于类声明中的函数自动成为内联函数;但每个使用内联函数的文件都需要对其进行定义。
  3. 创建相应的对象时,每个对象都有自己的存储空间,用于存储内部变量和类成员;但同一个类的所有对象共享同一组成员函数,即每个成员函数只有一个副本,所有对象执行同一个代码块,只是这些代码块用于不同的数据。

3. 构造函数和析构函数

3.1 构造函数

  1. 作用:是一种特殊的类成员函数,在创建类对象时被自动调用,将值赋给数据成员。
  2. 声明和定义构造函数:1)无返回类型; 2)通过函数重载,可以创建多个同名但特征标不同的构造函数;3)其参数不能是数据成员,而是给数据成员赋值的变量,因此名称不能与数据成员一样。
  3. 使用构造函数
    1)显示调用:Stock food = Stock("ABC",20,10.0);
    2)隐式调用:Stock food ("ABC" ,20,10.0);
    3)构造函数只能用来创建对象,而不能通过对象来调用构造函数。
  4. 默认构造函数
    1)默认构造函数没有参数,声明中不包括值;
    2)如果定义了其他构造函数,程序员必须为类提供默认构造函数;
    3)定义默认构造函数的2种方法:一是给已有的构造函数的所有参数提供默认值;二是通过函数重载来定义一个没有参数的构造函数;一般情况下最好采用一方法

3.2 析构函数

  1. 作用
    1)用来释放对象使用的资源,并销毁对象的非静态数据成员;
    2)无论何时一个对象被销毁时,都会自动调用其析构函数。
  2. 原型格式:~类名(); 析构函数没有参数,且每个类只有一个析构函数。
  3. 调用析构函数:
    1)静态存储类对象:析构函数在程序结束时自动调用;
    2)自动存储类对象:析构函数在程序执行完代码块时自动调用;
    3)new创建的对象:使用delete释放内存时析构函数自动调用;
    4)没有提供析构函数时:编译器自动调用一个默认析构函数。
  4. 1)初始化:Stock stock2 = Stock("abcd",2,2.0);
    2)赋值:Stock1 = Stock("ACD",10,50.0);
    第一条语句是初始化,在创建指定值的对象时,可能会创建临时对象,也可能不会;
    第二条语句是赋值,在赋值语句中使用构造函数总会在赋值之前创建一个临时对象。
    二者相比,初始化效率更高。
  5. const成员函数:当成员函数(类方法)不修改调用对象时,就应该将其声明为const成员函数,这样可以保证不会修改调用对象。

4. this指针

  1. 目的:当类成员函数需要设计两个对象时,就需要this指针。
  2. this指针是指向用来调用成员函数的对象,一般而言,所有的类方法都将this指针设置为调用该类方法的对象的地址。例如:
const Stock & Stock::topval(const Stock &s) const
{
	if(s.total_val > total_val)
		return s;
	else
		return *this;
}

top = stock1.topval(stock2);//this指针指向stock1,因为是stock1调用的topval()方法
  1. this指针:对象的地址
    1)this指针不占用大小,它不是对象的一部分,因此sizeof(this)是没有值的;
    2)this指针只在类成员函数中使用;
    3)this指针只能用于非静态成员函数;
    4)每个成员函数都有一个this指针;
    5)调用:
    一调用整个对象:*this
    二调用成员变量:this->变量名
    三调用成员函数:this->成员函数名()

5. 对象数组

  1. 声明:与标准类型数组一样,例如:Stock mystuff [4];
  2. 初始化对象数组:
    1)使用默认构造函数创建数组元素Stock mystuff [4];
    2)花括号中的构造函数创建临时对象
    3)将临时对象的内容复制到对应的元素中。
    例如:
Stock mystuff[4] = {
		Stock("a",12.5,20),
		Stock("b",200,2.0),
		Stock("c",130,3.25),
		Stock("d",60,6.5)
}

因此,要创建对象数组,那这个类必须有默认构造函数

6. 类作用域

  1. 类成员名的作用域是整个类,只在该类中已知,在类外未知,因此使用类成员名时,必须根据上下文使用直接成员运算符(.)、间接成员运算符(->)或作用域解析运算符(::)。
  2. 作用域为类的常量
    使用符号常量的作用域为类:
class B
{
private:
const int Months = 12;//invaild!!!
double costs[Months];
}

上面是错误的,因为类只有在创建对象时才分配内存,那么上面的语句是不能分配内存给costs的。
1)枚举常量:此方法不会创建类的数据成员,所有对象中都不包含枚举;由于创建的是枚举常量,而不是变量,因此可以不用枚举名。

class B
{
private:
enum {Months = 12};
double costs[Months];
}

2)静态变量static:该常量与其他静态常量存放在专门的一块内存中,而不是存储在对象中。

class B
{
private:
static int Months = 12;
double costs[Months];
}
  1. 作用域内的枚举
    1) 如果类中有两个枚举,其中定义的枚举量可能会发生冲突,C++11提供了一种新的枚举:
enum class egg{S,M,L,J};
enum class fruit{S,M,L,J};

并用枚举名来限定枚举量:

egg a = egg::L;
fruit b = fruit::L;

2) 转化为整型
–隐式转换:常规枚举可以自动转换为int型,但类作用域中的枚举不能隐式转换为int型;
–显式转换:int(egg::S);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值