对象和类

抽象和类

面向过程编程首先考虑要遵循的步骤,然后考虑如何表示这些数据。
面向对象编程(oop)首先考虑数据,不仅要考虑如何表示数据,还要考虑如何使用数据。

OOP特性:

  • 抽象
  • 封装和数据隐藏
  • 多态
  • 继承
  • 代码的可重用性

C++中的类

类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个整洁的包。

定义类:

  • 类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口。
  • 类方法定义:描述如何实现类成员函数。
    类成员可以是数据类型,也可以是函数。
#ifndef STOCK00_H_
#define STOCK00_H_

#include <string>

class Stock //类声明,将类名首字母大写
{
private://只能通过公共成员访问的类成员(数据隐藏)
std :: string company;
long shares;
double share_val;
...
public://公共接口的类成员
...
};

#endif

提示:不必在类声明中使用关键字private,因为这是类对象的默认访问控制。

实现类成员函数

两个特殊的特征:

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

void Stock :: update (double price) 成员函数头。

内联方法:其定义位于类声明中的函数都将自动成为内联函数,内联函数的链接性为内部的。

对于类对象的使用:
所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。

类的构造函数和析构函数

构造函数

构造函数:将类对象进行初始化。
构造函数的名称和类名相同,没有声明类型。

声明和定义构造函数

需要为Stock对象提供3个值,因此应该为构造函数提供3个参数,原型:

//使用默认参数的构造原型
Stock(const string & co, long n = 0, double pr = 0.0);

原型位于类声明的公有部分,没有返回类型。
构造函数的定义:

Stock :: Stock(const string & co, long n, double pr)
{
...
}

当程序声明对象时,将自动调用构造函数
注意:构造函数的参数表示的不是类成员,而是赋值给类成员的值。因此,参数名不能与类成员相同。

使用构造函数

显示地调用构造函数:
Stock food = Stock("World Cabbage", 250, 1.25);
隐式地调用构造函数:
Stock garment ("Furry Mason", 50, 2.5);

默认构造函数

默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。默认构造函数用于这种声明:
Stock cat;
当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,必须为它提供默认构造函数。

定义默认构造函数的方式(不要同时采用这两种方式):

  • 给已有构造函数的所有参数提供默认值:Stock(const string & co = "Error", int n = 0, double pr = 0.0);
  • 通过函数重载来定义另一个构造函数——一个没有参数的构造函数:Stock();

用户定义的默认构造函数通常给所有成员提供隐式初始值。
例如,为Stock类定义一个默认构造函数:

Stock :: Stock()
{
company = "no name";
shares = 0;
share_val = 0.0;
total_val = 0.0;
}

隐式调用默认构造函数时,不要使用圆括号。例如:
Stock second(); second()是一个返回Stock对象的函数。

析构函数

析构函数在类对象过期时会被自动调用,如果程序员没有提供析构函数,编译器会隐式地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数的定义。

在类的名称前加上~,析构函数没有参数,因此原型为:
~Stock();
可以编写为:

Stock :: ~Stock()
{
}

补充

  1. 在C++11中,可将列表初始化语法用于类。
  2. 为了保证函数不会修改调用对象,将const关键字放在函数的括号后面。
    void show() const;//函数声明
    void stock::show() const;//函数定义

this指针

const Stock & topval (const Stock & s) const;
该函数隐式地访问一个对象,而显示访问另一个对象。括号中的const表明,该函数不会修改被显示访问的对象;括号后的const表示函数不会修改被隐式访问的对象。由于函数返回两个const对象之一,因此返回类型也是const引用。

top = stock1.topval(stock2);

const Stock & Stock::topval(const Stock & s) const
{
	if(s.total_val>total_val)
		return s;
	else
		return ???;  //如何称呼这个对象
}
//this指针指向用来调用成员函数的对象,一般来说,所有的类方法将this指针设置为调用它的对象的地址。

类作用域

在类中定义的名称的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。

作用域为类的常量
因为声明类只是描述了对象的形式,并没有创建对象。

class Bakery
{
private:
	const int Months = 12;//出现错误

所以创建常量用下面两种方式:

  • 在类中声明一个枚举
class Bakery
{
private:
	enum {Months=12};//不会创建类数据成员,所有的对象都不包含枚举,Months只是个符号名称,在作用域为整个类的代码中遇到,编译器将用12替代。这里并不打算创建枚举类型的变量,所以不需要提供枚举名。
	double costs[Months];
	...
  • 使用关键字static。此时将常量与其他静态变量存储在一起,而不是存储在对象中。
class Bakery
{
private:
	static const int Months = 12;
	double costs[Months];
	...

作用域内枚举(C++11)

enum class egg {samll, medium};
enum class t_shirt {samll, medium};
//这样就不会发生枚举量冲突(当枚举量位于相同的作用域内会发生冲突)

安全性:位于作用域内枚举不能隐式地转换为整型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值