对象和类

对象和类
  类是用户定义的类型,对象是类的实例。

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

  在C++中,用户定义类型指的是实现抽象接口的类设计。

指定基本类型完成了三项工作:
• 决定数据类型需要的内存数量;
• 决定如何解释内存中的位(比如long和float在内存中占用的位数相同,但是在转换为数值时的方法不同);
• 决定可使用数据对象执行的操作或方法;

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

  公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。防止程序直接访问数据被称为数据隐藏。
  由于隐藏数据是OOP主要的目标之一,因此数据项通常放在私有部分,组成类接口的成员函数放在公有部分;也可以将成员函数放在私有部分中,不能直接从程序中调用这些函数,但公有的方法可以使用它们。
  结构的默认访问类型是public,而类为private。
  类声明中定义的函数都将自动称为 内联函数。

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

  指定类设计的第一步是提供类声明,第二步是实现类成员函数。

构造函数和析构函数
  常规的初始化语法不适合于类对象,因为程序操作了对象的私有数据,违背了数据隐藏的特性。构造函数就是为了让类对象的使用跟标准类型一样。
  构造函数没有返回类型,原型位于类声明的公有部分。不能将类成员变量直接用作构造函数的参数名,一般的做法是在类成员变量前加前缀_m或加后缀_ 。
  默认构造函数是在未提供显式初始值时,用来创建对象的构造函数。默认构造函数没有参数,因为声明中不包含值。当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。*为类定义了构造函数后,必须为它提供默认构造函数。*如果提供了非默认构造函数,但没有提供默认构造函数,在创建对象时将出错。这样做的原因是禁止创建为初始化的对象。
  定义默认构造函数的方式有两种:一种是给已有构造函数的所有参数提供默认值;另一种是通过函数重载来定义另一个构造函数——一个没有参数的构造函数。在设计类时,通常应提供对所有类成员做隐式初始化的默认构造函数。

  析构函数也可以没有返回类型和声明类型。与构造函数不同的是析构函数没有参数。

创建对象的方式

Stock stock1("name", 12, 20.0);
Stock stock2 = Stock ("name", 12, 20.0);

  特别说明第二种方式,它使用构造函数创建一个临时的对象 ,然后将临时对象复制到stock2中,最后调用析构函数删除临时对象。如果即可以通过初始化,也可以通过赋值来设置对象的值,则应采用初始化的方式,因为效率更高。

列表初始化

Stock stock2 = {"name", 12, 20.0};
Stock stock2 {"name", 12, 20.0};
Stock stock2 {};

  提供某个构造函数的参数列表匹配的内容,并用大括号将它们括起。

const成员函数

const Stock stock2 = Stock ("name", 12, 20.0);
stock2 .show();

  上述代码中第二行将被编译器拒绝,因为show可能会修改对象,但对象又是const声明的,不能被修改。为保证成员函数不会修改调用对象。C++的解决方法是将const关键字放在函数的括号后面。

void show() const;

  一般来说只要类的方法不修改调用对象,就应将其声明为const。

this指针
  this指针指向用来调用成员函数的对象(this被作为隐藏参数传递给方法)。每个成员函数都包含一个this指针,指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。

对象数组
  当程序创建未被显示初始化的类对象时,总是调用默认构造函数。如果类包含多个构造函数,则可以对不同的元素使用不同的构造函数。

Stock stocks[3] = {
	Stock ("name", 12, 20.0),
	Stock (),
	Stock ("abc", 34, 56.0)
};

  初始化对象数组的过程是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中,因此要创建对象数组,则这个类必须有默认构造函数。

类作用域
  在类中定义的名称(如类数据成员名和类成员函数名)的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。因此,可以在不同的类中使用相同的类成员名而不引起冲突。
作用域为类的常量:
  有时候,使符号常量的作用域为类很有用,比如在类声明中使用(int leng = 10;)来指定数组的长度,但是这是不行的,因为声明类只是描述了对象的形式,并没有创建对象,也就是没有存储值的空间。虽然C++提供了成员初始化,但是不适用于数组声明。C++提供了两种方式来实现这个目标。第一种方式是在类中声明一个枚举。它 可以为整型常量提供作用域为类的符号名称。

class Bakery
{
	enum {Months = 12};
	double costs[Months];
};

  注意,用这种方式声明枚举并不会创建类数据成员,也就是说所有对象中都不包含枚举。Months只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用12来代替它。由于这里使用枚举只是为了创建符号常量,并不打算创建枚举类型的变量,因此不需要提供枚举名。另一种在类中定义常量的方式是使用关键字static;使用static修饰的常量将和其它静态变量存储在一起,而不是存储在对象中。

  传统枚举可能发生两个枚举定义中的枚举量可能发生冲突。C++11提供了一种新枚举,其枚举的作用域为类。也可使用关键字struct替代class。

enum class egg {small, medium};
enum class big {small, medium};
egg choice = egg::small;
big dsv = big::small;

  默认情况下,C++11作用域内枚举的底层类型为int,但也提供了一种语法来做出不同的选择。

enum class : short pizza {small, medium};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值