CPP 10. 对象和类 2020-11-07 浏览量 670 暂无评论 # 第10章 对象和类 ## 目录 - [过程性编程和面向对象编程](#过程性编程和面向对象编程) - [类概念]() - [如何定义和实现类]() - [公有类访问和私有类访问]() - [类的数据成员]() - [类方法(类函数成员)]() - [创建和使用类对象]() - [类的构造函数和析构函数]() - [const成员函数]() - [this指针]() - [创建对象数组]() - [类作用域]() - [抽象数据类型]() ## 10.1 过程性编程和面向对象编程 过程性编程首先考虑要遵循的步骤,然后考虑如何表示数据;OOP首先考虑数据--如何表示数据、如何使用数据。 ## 10.2 抽象和类 类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个简洁的包。 🐸小知识: 1. 使用同一个类所创建的不同对象都有自己的存储空间,用于存储内部变量和类成员,但是同一个类的所有对象共享同一组类方法; **定义类** 类规范由两部分组成: 1. 类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口;(蓝图) 2. 类方法定义:描述如何实现类成员函数。(细节) ```cpp // 通常将接口(类定义)放在头文件中,并将实现(类方法的代码)放在源代码文件中 // stock.h -- Stock class interface // verson 00 #ifndef STOCK00_H_ #define STOCK00_H_ #include 公有成员函数是程序和对象的私有成员之间的桥梁,程序不能直接访问私有数据,这被称为数据隐藏 C++中包括了许多专门用来实现OOP方法的特性,例如 1. 将数据表示和函数原型放在一个类声明中,来使描述成为一个整体, 2. 隐藏数据是OOP主要的目标之一--让数据表示成为私有,使得数据只能被授权的函数访问 class Stock { // private可以省略,默认的 private: std::string company; long shares; double share_val; double total_val; // 定义位于类声明中的函数将自动成为内联函数 void set_tot() {total_val = shares * share_val;} public: void } ``` ## 10.3 类的构造函数和析构函数 作用是让使用类对象能像使用标准类型一样,比如可以初始化。 ### 10.3.1 构造函数 类构造函数专门用于构造新对象、将值赋给它们的数据成员,C++已经为这些成员函数提供了名称和使用语法,需要程序员提供方法定义,程序声明对象时,将自动调用构造函数。 🐸小知识: 1. 当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数,为类定义了构造函数后,程序员就必须为它提供默认构造函数; 2. 构造函数的声明和定义 ```cpp Stock(const string & co, long n = 0, double pr = 0.0); 注意,这里的形参不能和类数据成员的名称相同,可以在数据成员名中使用m_前缀或者_后缀 Stock::Stock(const string & co, long n, double pr) { company = co; if (n < 0) { std::cerr << "Number of shares can't be megative; " << company << " shares set to 0.\n"; shares = 0 } else shares = n; share_val = pr; set_tot(); } // 默认构造函数,没有任何参数 Stock::Stock() { company = "no name"; shares = 0; share_val = 0.0; total_val = 0.0; } // 显式 Stock food = Stock("World Cabbage", 250, 1.25); // 隐式 Stock food("World Cabbage", 250, 1.25); Stock food {"World Cabbage", 250, 1.25}; Stock food = {"World Cabbage", 250, 1.25}; ``` ### 10.3.2 析构函数 析构函数完成清理工作,在类对象过期时自动被调用。 如果构造函数使用了new,则必须提供使用delete的析构函数。 ```cpp // 原型 ~Stock(); // 定义 Stock::~Stock() { cout << "Bye, " << company << "!\n"; } ``` ### 10.3.3 const成员函数 const对象不能调用非const成员函数,声明和定义const成员函数 ```cpp void show() const; void stock::show() const ``` ## 10.4 this指针 刚才的每个类成员函数都只涉及一个对象,但有时候方法可能涉及两个对象,这时候就需要用到C++的this指针,它指向用来调用成员函数的对象。 ```cpp const Stock & Stock::topval(const Stock & s) const { if (s.total_val > total_val) return s; else return *this; } ``` ## 10.5 对象数组 初始化对象数组的方案:首先使用默认构造函数创建数组元素,然后使用花括号中的构造函数创建临时对象,然后将临时对象的内容复制到响应的元素中。**因此,要创建类对象数组,这个类必须有默认构造函数。** ```cpp Stock mystuff[4]; const int STKS = 4; Stock stocks[STKS] = { Stock("A", 12.5, 20), Stock(); Stock("B", 10.2, 20) }; 只初始化了3个,余下的1个使用默认构造函数进行初始化 ``` ## 10.6 类作用域 在类中定义的名称(如类数据成员和类成员函数名)的作用域都为整个类,只在该类中是一直的,在类外不可知,因此,不同类中的同名成员是不同的。 **作用域为类的常量** ```cpp class Bakery { private: const int Months = 12; // 这是不对的,因为声明类只是描述了对象的形式 double costs[Months]; } 1. 可以使用枚举来实现 class Bakery { private: enum {Months = 12}; double costs[Months]; } 2. 使用static关键字 class Bakery { private: static const int Months = 12; double costs[Months]; } ``` ## 10.7 抽象数据类型 ### 10.7.1栈 - 可创建空栈 - 可将数据项添加到堆顶 - 可从栈顶删除数据项 - 可查看栈是否填满 - 可查看栈是否为空 ```cpp // stack.h #ifndef STACK_H_ #define STACK_H_ typedef unsigned long Item; class Stack { private: enum {MAX = 10}; Item items[MAX]; int top; public: Stack(); bool isempty() const; bool isfull() const; bool push(const Item & item); bool pop(Item & item); }l #endif ``` 赞赏 微信支付 支付宝支付