本章开始学习面向对象编程。
9.1 类和对象
9.1.1 声明类
声明类使用class,声明类不会对程序执行产生影响。
9.1.2 作为类实例的对象
要使用类的功能,需要创建其实例--对象,并通过对象访问成员方法和属性。
创建对象和创建其他类型的实例类似。
double pi= 3.1415;
class object name;
类似为其他对象动态分配内存,也可以使用new为class分配内存。
int* pointToNum = new int; //an integer allocate dynamically
delete pointToNum; // de-allocating memory when done using
Human* firstWoman = new Human(); //dynamically allocated Human
delete firstWoman; //de-allocating memory
9.1.3 使用句点运算符(.)访问成员
使用(.)访问对象属性和方法。
9.1.4 使用指针运算符(->)访问成员
如果对象是使用new在一走存储区实例化的,或者有指向对象的指针。可以使用指针运算符(->)来访问成员属性和方法。
Human* firstWoman = new Human();
firstWoman->dateOfBirth = "1993";
firstWoman->InttoduceSelf();
delete firstWoman;
9.2 关键字public 和 private
pubilc可以将类的方法和属性定义为私有,private可以声明为私有。只能在类的内部或者其友元才能访问。
class Human {
private:
int age;
char name;
public:
int GetAge() {
return age;
}
void SetAge(int humansAge) {
age = humansAge;
}
};
上述例子中不能之间通过定义对象eve,eve.age()访问age,只能通过eve.GetAge()访问age。也不能通过eve.age = 22赋值,只能通过eve.SetAge()赋值。如果没实现public方法访问age。age就不会被访问。
c++让类的设计者能够控制类属性的访问和操纵方式。
使用private实现数据抽象
如果不想显示真实数据,比如希望年龄小,将GetAge返回age-2即可实现数据抽象。
在面对对象编程中,抽象是一个重要概念。使用者能决定哪些属性只能让类及其成员知道,类外的任何人都不能访问(友元除外)
9.3 构造函数(constructor)
构造函数是一种特殊的函数(方法),在根据类创建对象时被调用。与函数一样可以被重载。
9.3.1 声明和实现构造函数
构造函数是一种特殊的函数,与类同名且不返回任何值。
class Human{
public:
Human() //declaration of a constructor
}
构造函数可以在类声明中实现,也可以在类声明外实现。在类声明中实现如下:
class Human
{
public:
Human()
{
}
}
在类声明外定义构造函数的代码如下:
class Human
{
public:
Human(); //constructor declaration
}
//constructor implementaion (definition)
Human::Human()
{
//constructor code here
}
:: 为作用域解析运算符,Human::age表示Human类中声明的变量age,::age表示全局作用域中的变量age。
9.3.2 何时及如何使用构造函数
构造函数总是在创建对象时被调用,被用来初始化成员变量(int,指针等)。不然未初始化的变量可能包含垃圾值。有了构造函数忘记给对象初始化值也没事,构造函数将确保对成员变量初始化。
9.3.3 重载构造函数
与函数一样,构造函数也可被重载。
class Human
{
public:
Human()
{
// default constructor code
}
Human(string humansName)
{
// overloaded constructor code
}
}
包含多个构造函数的类:
class Human {
private:
int age;
string name;
public:
Human() {
//default constructor,name and age not set
age = 0;
}
Human(string humanName, int humanAge)
{ //overload constructor
name = humanName;
age = humanAge;
}
};
int main()
{
Human firstMan;//use default constructor
Human firstWoman("eve", 20); //use overloaded constructor
}
如果没有默认构造函数,创建每一个对象都只能使用姓名和年龄作为参数的构造函数。不提供就无法创建对象。属于private的成员在构造函数赋值之后,如果没有定义SetAge这样的函数将无法修改。
构造函数可以带默认值,如设置humanAge=25,创建对象时可提供humanAge也可以不提供。
默认构造函数是指调用时可以不提供参数的构造函数,如果构造函数有两个参数,但是都有默认值。它也是默认构造函数。
9.3.6 包含初始化列表的构造函数
使用初始化列表构造函数时,初始值可以是参数也可以是固定的值。使用特定参数调用基类的构造函数时初始化列表也很有用。
class Human {
private:
int age;
string name;
public:
Human() {
//default constructor,name and age not set
age = 0;
}
Human(string humanName = "Adam", int humanAge = 25)
:name(humanName), age(humanAge)
{ //overload constructor
name = humanName;
age = humanAge;
}
};
9.4 析构函数(destructor)
构造函数在实例化对象时被调用,析构函数在对象被销毁时自动被调用。析构函数前面有(~)腭化符号。
class Human {
private:
int age;
string name;
public:
Human();
~Human(); //declaration of a destructor
};