1. 对象的感念
面向对象的编程方式就是根据问题所特定的对象类型来解决该问题,而不是采用计算机处理数字和字符的低级方式来解决问题。
在C++编程术语中,对象是数据类型的一个实例。例如:在定义一个变量时,常常使用下面的语句:
string saying = “A good horse cannot be of a bad color.”; |
这里定义了string类型的一个实例。我们给这个实例指定了名称,称之为saying。于是可以说,变量saying是类型string的一个对象。
类就是用户定义的数据类型,在大多数情况下,定义类时使用关键字class。
注意:不要把类和typedef语句或枚举的用法混淆了。typedef语句不创建新类型,只是为已有的类型定义一个别名。每个枚举都是一独特的类型。但它不是一个类。类是全新的、原始的类型,它不仅有一组惟一的属性,还有可应用于类对象的操作,这些完全是由用户定义的。
定制数据类型的另外两种方法:
· 联合:用union关键字来创建新类型。
· 结构:用struct关键字来创建新类型。
2. C++中的结构
实际上,C++结构的功能可以用类来替代。
结构的功能同样可以应用到类上。
定义结构类型
struct Book { char title[80]; char author[80]; char publisher[80]; int year; }; |
注意:这个声明没有定义任何变量,它指定了一个新类型Book。编译器会把这个定义用作蓝图,来创建类型Book的实体。
声明结构类型的变量
定义了结构Book后,如何定义这种类型的变量。定义Book类型的变量与定义其他类型的变量一样:
Book paperback; |
或者,下面3个语句定义了3个变量:
Book novel; Book* ptravel_guide; Book languae_guide[10]; |
可以定义结构类型时定义变量:
struct Book { char title[80]; char author[80]; char publisher[80]; int year; } dictionary, thesaurus; |
这个语句定义了类型Book,接着定义了这种类型的两个变量dictionary,thesaurus。
但是,最好把类型定义放在单独的一个语句中。一般情况下,需要使用任何数据类型时,类型定义放在头文件中,并把相应的头文件包含到.cpp文件中。
创建结构类型的对象
方法一:在初始化列表中为数据成员定义初始值。
Book novel = { "Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996 }; |
提示:如果Book的成员是类类型,如string,就不能以这种方式初始化Book对象。原因是类类型的对象只能通过调用一个特殊的函数即构造函数来创建。也就是说,结构不是一个聚合。
方法二:也可以初始化结构变量的数组,方法与初始化多为数组一样。如:
Book novel[] = {"Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996}, {"Tring to Save Piggy Sneed ", "Bloomsbury ", "John Irving ", 1993}, {"Illywhacker ", "Peter Carey ", "Faber & Faber ", 1985}; |
访问结构对象的成员
把值1994赋给结构novel的成员year:
nover.year=1994; |
可以在算数表达式中使用结构变量的成员,其方法与使用同一类型的其他变量一样。给成员year加上2,使用下面语句:
novel.year += 2; |
访问结构数组元素的成员:下面计算数组novels中第一本书和最后一本书的出版时间间隔,如下:
int interval=novels[0].year – novels[2].year; |
代码:使用结构
#include <iostream>
using namespace std;
struct Box
{
double length;
double width;
double height;
};
double volume(const Box& aBox);
int main()
{
Box firstBox={80.0, 50.0, 40.0};
double firstBoxVolume=volume(firstBox);
cout << endl;
cout << "Size of first Box object is "
<< firstBox.length << " by "
<< firstBox.width << " by "
<< firstBox.height
<< endl;
cout << "Volume of first Box object is " << firstBoxVolume
<< endl;
Box secondBox=firstBox;
secondBox.length *=1.1;
secondBox.width *=1.1;
secondBox.height *=1.1;
cout << "Size of second Box object is "
<< secondBox.length << " by "
<< secondBox.width << " by "
<< secondBox.height
<< endl;
cout << "Volume of second box object is "<<volume(secondBox)
<< endl;
cout << "Increasing the box dimensions by 10% has increased the volume by "
<< static_cast<long>((volume(secondBox)-firstBoxVolume)*100.0/firstBoxVolume)
<< "%"
<< endl;
return 0;
}
double volume(const Box& aBox)
{
return aBox.length* aBox.width* aBox.height;
}
结构的成员函数
接上面的代码,可以在Box类型定义中定义volume()函数,使它成为Box对象的一个成员,是每个Box对象的一个组成部分。下面把volume()函数定义为结构的一个函数成员:
struct Box { double length; double width; double height;
//在Box类型定义中定义volume()函数 double volume() { return length*width*height; } }; |
该函数现在成为类型的一个组成部分,只能在Box类型的对象中使用该函数。
放置成员函数的定义
struct Box { double length; double width; double height;
//在Box类型定义中放置volume()函数的定义 double volume(); }; |
对结构使用指针
可以创建一个指针指向结构类型的变量,或指向用户定义的其他类型。
例如:要定义指向Box对象的指针:
Box* pBox=0; |
这个指针可以保存一个Box类型的对象的地址,之力把它初始化为0。
假定已经定义了一个Box对象aBox,就可以按通常的方法把指针设置为这个变量的地址,即使用地址运算符:
pBox=&aBox; |
在自有存储区创建对象
使用new运算符,也可以在自有存储区创建Book类型的对象。
Book pDictionary = new Book; |
在使用完这个对象后,必须以通常的方式从自有存储区中删除它:
delete pDictionary; |
通过指针访问结构成员
假定下面的语句定义了一个Box对象:
Box theBox = {80.0, 50.0, 40.0}; |
可以声明一个指向Box对象的指针,用theBox的地址初始化它,如:
Box* pBox = &theBox; |
可以使用指针pBox访问它指向的对象的数据成员。这需要两步:
首先,必须解除指针的引用,获得对象。
再,使用该对象、成员选择运算符和成员名称。
指针成员访问运算符
通过指针访问用户定义类型的对象成员
(*pBox).height += 10.0; |
使用指针成员访问运算符来表示:
pBox->height += 10.0; |
代码:使用对象指针:这个例子包含三个文件
一个包含Box结构定义的头文件,如下:
<�D t@��~-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'>,接着定义了这种类型的两个变量dictionary,thesaurus。但是,最好把类型定义放在单独的一个语句中。一般情况下,需要使用任何数据类型时,类型定义放在头文件中,并把相应的头文件包含到.cpp文件中。
创建结构类型的对象
方法一:在初始化列表中为数据成员定义初始值。
Book novel = { "Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996 }; |
提示:如果Book的成员是类类型,如string,就不能以这种方式初始化Book对象。原因是类类型的对象只能通过调用一个特殊的函数即构造函数来创建。也就是说,结构不是一个聚合。
方法二:也可以初始化结构变量的数组,方法与初始化多为数组一样。如:
Book novel[] = {"Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996}, {"Tring to Save Piggy Sneed ", "Bloomsbury ", "John Irving ", 1993}, {"Illywhacker ", "Peter Carey ", "Faber & Faber ", 1985}; |
访问结构对象的成员
把值1994赋给结构novel的成员year:
nover.year=1994; |
可以在算数表达式中使用结构变量的成员,其方法与使用同一类型的其他变量一样。给成员year加上2,使用下面语句:
novel.year += 2; |
访问结构数组元素的成员:下面计算数组novels中第一本书和最后一本书的出版时间间隔,如下:
int interval=novels[0].year – novels[2].year; |
代码:使用结构
//File: box.h
#ifndef BOX_H
#define BOX_H
struct Box
{
double length;
double width;
double height;
double volume();
};
#endif
一个包含Box结构成员函数定义的源文件,如下:
//File: box.cpp
#include "box.h"
double Box::volume()
{
return length*width*height;
}
一个包含main()的源文件,如下:
#include <iostream>
#include "box.h"
using namespace std;
int main()
{
Box aBox={10, 20, 30};
Box* pBox=&aBox;
cout << endl
<< "Volume of aBox is " << pBox-> volume() << endl;
Box* pdynBox = new Box;
pdynBox->height = pBox->height +5.0;
pdynBox->length = pBox->length -3.0;
pdynBox->width = pBox->width -2.0;
cout << "Volume of Box in the free store is " << pdynBox->volume() << endl;
delete pdynBox;
return 0;
}
对象指针的应用
类类型的对象指针的三种应用:
· 在自由存储区中创建或访问对象时,必须使用指针。
· 链表,结构的数据成员不能包含该结构类型的成员,不能把Book结构定义为包含Book数据类型。但是结构可以包含指向该结构类型的指针。
· 对象指针最重要的应用是实现多态性。多态性是面向对象编程的一个基本机制。
1. 联合
联合是一种数据类型,它允使用同一个内存块在不同的时间存储不同的类型的值。联合中的变量称为联合的成员。
使用联合的3种方式:
1. 使用联合在同一个内存块中存储程序中不同时期的不同变量(其类型也可能不同)。最初的想法是让内存的使用更经济,现在已经不存在这个问题,因此不推荐这个方法——动态分配内存也可以获得相同的效果。
2. 涉及数组,主要为了节省大量内存。
3. 可以使用联合以两种或更多种不同的方式来解释相同的数据
声明联合
union ShareLD { double dVal; long lVal; }; |
匿名联合
union { char* pVal; double dVal; long lVal; }; |
注意,如果声明了没有名称的联合,但同一个语句中又声明了该类型的对象,联合就不是匿名的。如:
union { char* pVal; double dVal; long lVal; }uvalue; |
首先,必须解除指针的引用,获得对象。
再,使用该对象、成员选择运算符和成员名称。
指针成员访问运算符
通过指针访问用户定义类型的对象成员
(*pBox).height += 10.0; |
使用指针成员访问运算符来表示:
pBox->height += 10.0; |
代码:使用对象指针:这个例子包含三个文件
一个包含Box结构定义的头文件,如下:
<�D t@��~-family:宋体;mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'>,接着定义了这种类型的两个变量dictionary,thesaurus。但是,最好把类型定义放在单独的一个语句中。一般情况下,需要使用任何数据类型时,类型定义放在头文件中,并把相应的头文件包含到.cpp文件中。
创建结构类型的对象
方法一:在初始化列表中为数据成员定义初始值。
Book novel = { "Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996 }; |
提示:如果Book的成员是类类型,如string,就不能以这种方式初始化Book对象。原因是类类型的对象只能通过调用一个特殊的函数即构造函数来创建。也就是说,结构不是一个聚合。
方法二:也可以初始化结构变量的数组,方法与初始化多为数组一样。如:
Book novel[] = {"Feet of Clay ", "Terry Pratchett ", "Victor Gollanz ", 1996}, {"Tring to Save Piggy Sneed ", "Bloomsbury ", "John Irving ", 1993}, {"Illywhacker ", "Peter Carey ", "Faber & Faber ", 1985}; |
访问结构对象的成员
把值1994赋给结构novel的成员year:
nover.year=1994; |
可以在算数表达式中使用结构变量的成员,其方法与使用同一类型的其他变量一样。给成员year加上2,使用下面语句:
novel.year += 2; |
访问结构数组元素的成员:下面计算数组novels中第一本书和最后一本书的出版时间间隔,如下:
int interval=novels[0].year – novels[2].year; |
代码:使用结构