《C++ Primer Plus》读书笔记 第10章 对象和类

第10章 对象和类

1.C++中的类

一般来说,类规范由两个部分组成:

  • 类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口。
  • 类方法定义:描述如何实现类成员函数。

通常,C++程序员将接口(类定义)放在头文件中,并将实现(类方法的代码)放在源代码文件中。

class Stock
{
private:
	std::string company;
	long shares;
	double share_val;
	double total_val;
	...
public:
	void acquire(const std::string & co, long n, double pr);
	void buy(long num, double price);
	void sell(long num, double price);
	...
};

其中,关键字private表示后面的对象成员为私有。关键字public表示后面的对象成员为公有

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

C++中类和结构的唯一区别是,结构的默认访问类型是public,而类为private。

类方法的完整名称中包括类名。Stock::buy()是函数的限定名;而简单的buy()是全名的缩写(非限定名),它只能在类作用域中使用。

方法可以访问类的私有成员。非成员函数只能访问类的公有成员(友元除外)。

类声明会自动将短小的成员函数作为内联函数,所以定义位于类声明中的函数如果符合内联函数的要求,这个方法将会自动成为内联函数。内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用的、最简便的方法是:将内联定义放在定义类的头文件中。

2.构造函数

类构造函数专门用于构造新对象、将值赋给它们的数据成员。

class Stock
{
	...
public:
	Stock(const string & co, long n = 0, double pr = 0.0);
	...
};

下面是构造函数的定义:

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

构造函数的参数名不能与类成员相同,否则最终的代码将会造成混乱,一种常见的做法是在数据成员名中使用 m_ 前缀。另一种常见的做法是在成员名中使用后缀_。

C++提供了两种使用构造函数来初始化对象的方式。第一种方式是显式地调用构造函数:

Stock food = Stock(“World Cabbage”, 250, 2.5);

另一种方式是隐式地调用构造函数:

Stock garment(“Furry Mason”, 50, 2.5);

下面是将构造函数与new一起使用的方法:

Stock *pstock = new Stock(“Electroshock Games”, 18, 19.0);

默认构造函数是在未提供显式初始值时,用来穿件对象的构造函数。也就是说,它是用于下面这种声明的构造函数:

Stock fluffy_the_cat;

当且仅当没有定义任何构造函数时,编译器会自动提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数。如果提供了非默认构造函数,但没有提供默认构造函数,则下面的声明将出错:

Stock Stock1;

定义默认构造函数的方式有两种。一种是给已有构造函数的所有参数提供默认值:

Stock(const string & co = “Error”, int n = 0, double pr = 0.0);

另一种方式是通过函数重载来定义另一个构造函数——一个没有参数的构造函数:

Stock();

可以利用列表初始化的方式对某个对象进行初始化,只需要提供与某个构造函数的参数列表匹配的内容,并用大括号将它们括起:

Stock hot_tip = {“Derivatives Plus Plus”, 100, 45.0};
Stock jock {“Sport Age Storage, Inc”};
Stock temp {};

3.析构函数

用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将自动调用一个特殊的成员函数——析构函数。析构函数完成清理工作。例如,如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存。如果没有显式地为类定义析构函数,编译器会自动生成一个隐式析构函数。

析构函数的名称是在类名前加上“~”。另外,和构造函数一样,析构函数没有返回值和声明类型。且析构函数没参数。因此Stock类的析构函数的原型必须是这样的:

~Stock();

4.const成员函数

只要类方法不修改调用对象,就应该将其声明为const。以这种方式声明和定义的类函数被称为const成员函数

void show() const;	//声明
void stock::show() const	//定义

这样,对于一个const对象,就可以调用const成员函数:

const Stock land = Stock{“Kludgehorn Properties”};
land.show();

5.this指针

每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。

下面是一个Stock类的方法,用于比较两个Stock对象中total_val的大小,并返回较大的那个对象:

const Stock & Stock::topval(const Stock & s) const
{
	if(s.total_val > total_val)
		return s;
	else
		return *this;
}

6.对象数组

声明对象数组的方法与声明标准类型数组相同:

Stock stocks[4];

可以用构造函数来初始化数组元素:

Stock stocks[4] = {
	Stock(“NanoSmart”, 12.5, 20),
	Stock(),
	Stock(“Monolithic Obelisks”, 130, 3.25)
};

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

7.类作用域

在类声明或成员函数定义中,可以使用未修饰的成员名称。在其他情况下,使用类成员名时,必须根据上下文使用直接成员运算符(.)、间接成员运算符(->)或作用域解析运算符(::)。

在类中声明一个作用域为类的常量的方法有两种:

第一种方式是在类中声明一个枚举。在类声明的枚举的作用域为整个类,因此可以用枚举型常量提供作用域为整个类的符号名称:

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

第二种方式是使用关键字static:

class Bakery
{
private:
	static const int Months = 12;
	double costs[Months];
	...
};

这将创建一个名为Months的常量,该常量将与其他静态变量存储在一起,而不是存储在对象中。因此,只有一个Months常量,被所有Bakery对象共享。

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

传统的枚举存在一些问题,其中之一是两个枚举定义中的枚举量可能发生冲突:

enum egg {Small, Medium, Large, Jumbo};
enum t_shirt {Small, Medium, Large, Xlarge};

这将无法通过编译,因为egg Small和t_shirt Small位于相同作用域内,它们将发生冲突。为避免这种问题,C++11提供了一种新枚举,其枚举的作用域为类:

enum class egg {Small, Medium, Large, Jumbo};
enum class t_shirt {Small, Medium, Large, Xlarge};

也可以使用关键字struct代替class。无论使用哪种方式,都需要使用枚举名来限定枚举量:

egg choice = egg::Large;
t_shirt Floyd = t_shirt::Large;

在有些情况下,常规枚举可以自动转换为整形,如将其赋给int变量或用于比较表达式时,但作用域内枚举不能隐式地转换为整形,但在必要时可以进行显式类型转换。

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

enum class : short pizza {Small, Medium, Large, Xlarge};

:short将底层类型制定为short。底层类型必须为整形

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值