结构体内的函数被称为成员函数,结构体中的数据则称为数据成员
扩展的结构体被称为类,结构体类型的变量被称为对象
C++11 允许为数据成员提供一个类内初始值,创建对象时,类内初始值将用于初始化数据成员,没有初始值的成员将被默认初始化,数据成员类内初始值只能放在等号“=”右边,或者放在花括号“{}”里,不能使用圆括号“()”,成员函数直接在类内定义,也可以在类外定义
成员函数的类外定义语法
类外定义的成员函数名字前面要加类名字和作用域符“::”,表示这个函数是在其所属的类作用域内,是这个类的成员函数,不同于全局函数
struct 类名
{
public:
公有成员声明;
private:
私有成员声明;
protected:
被保护成员声明;
};
private 成员只能由类自己的成员函数或友元访问,protected 成员可以由类自己的成员函数、友元、派生类成员访问
this指针
每个成员函数都有一个隐含的参数,指向接收消息的对象,称为this指针,X类的this指针的类型是X*,this指针是一个常量,含有当前实施调用的对象的地址。不能改变this指针的值,也不能取this指针的地址
this指针在成员函数中的用途:区分与数据成员同名的变量 ,返回当前对象,取得当前对象地址
友元
如果想让非成员函数访问一个类中的私有数据,应该在类中将这个函数声明为friend。一个类的友元可以访问该类的私有数据,在声明友元时要遵循一条规则:友元必须在被访问的类中声明
一个类的友元可以是:全局函数,另一个类的成员函数,另一个类
类A是类B的友元表示A的所有成员函数都是B的友元
friend关系不可传递。如果A是类B的友元,而类B是类C的友元,A不会自动成为C的友元
应该尽量避免使用友元,友元会破坏类的封装性,增加类之间的耦合度。
构造函数
构造函数在创建对象时被自动调用,负责初始化对象。构造函数的名字和类名字相同,它没有返回类型,参数通常为数据成员提供初始值,可以重载。在创建对象时,编译器会根据初始值的类型和个数来调用相应的构造函数。构造函数的形式决定了初始化对象的方式。
类中有些成员不能使用赋值的方式提供初始值,如:引用成员,const 数据成员,类类型的数据成员。用构造函数初始化列表,初始化列表位于构造函数的参数表之后,函数体之前,形如:构造函数(参数表) : 初始化列表 { 函数体 }
初始化列表形如:成员1(初始值1)[,成员2(初始值2),…]
在初始化列表中,直接初始化数据成员,效率更高,但如果成员是const、引用,或者是未提供默认构造函数的类类型,就必须通过构造函数初始化列表提供初值
在初始化列表中,每个成员只能出现一次,成员初始化的顺序与它们在类定义中出现的顺序一致,初始化列表中初值排列的顺序不影响实际的初始化顺序,如果可能的话,尽量避免用某些成员初始化其他成员。
委托构造函数
使用所属类的其他构造函数执行自己的初始化过程,把部分或全部职责委托给了其他构造函数
语法形式:
ClassName(参数表):ClassName(参数表){函数体}
析构函数
析构函数负责在对象生存期结束时返回相关资源和自动释放资源。当对象离开作用域时,或者用delete 释放在堆上创建的对象时,析构函数都会被自动调用。析构函数的名字是类名字前加波浪线“~”,析构函数没有返回类型,也没有任何参数,不能重载,只能为一个类定义唯一一个析构函数。
如果一个类只包含按值存储的数据成员,则析构函数不是必须定义的;如果类中没有定义析构函数,编译器在需要时会自动合成一个析构函数。
const 数据成员
在数据成员声明前加const 关键字就将其限定为常量,const 数据成员在构造函数的初始化列表中初始化,创建对象时初始化其中的const 数据成员,之后const 成员的值在对象的整个生存期中都不会改变。类的对象也可以由const 限定为常量。
const成员函数
返回类型 成员函数名(参数表) const { 函数体 }
将一个成员函数声明为const,表明这个成员函数不会修改对象的数据成员,能保证对象的常量性,对于在类外定义的const成员函数,必须在它的定义和声明中同时指定关键字const 。
只有声明为const 的成员函数才可以被const 对象调用,const 成员函数中不能修改类的数据成员,const 成员函数中不能调用其他非const 成员函数。
如果成员函数是非const 的,则只有非const 对象可以调用它;const 对象不能调用非const 的成员函数。如果成员函数是const 的,则const 对象可以调用它;非const 对象也可以调用它,不会改变对象中的成员。
staic数据成员
static数据成员对整个类类型只有一个,只能定义一次,由这个类型的所有对象共享访问,不会与全局域中的其他名字产生冲突,可以实现信息隐藏。static成员可以是private成员,而全局变量不能。在类的数据成员声明前加关键字static,就使该数据成员成为静态的
static数据成员属于类,不属于某个特定对象,因而不能在构造函数中初始化。static数据成员可以是任何类型,甚至是所属类的类型
可以用static const定义类中的常量,static const 数据成员在类外初始化。整值类型的static const可以在类定义里初始化,其他类型不能在类中初始化
在类的成员函数中可以直接访问static数据成员,在非成员函数中通过成员访问运算符“.”或“->”访问static数据成员,static成员只有一个副本,可以直接用类名字限定的静态成员名字访问。注意:static成员仍然遵循访问控制的约束
声明语法是在类定义中的函数声明前加static 关键字,在类外定义时不需要加关键字static
static成员函数没有this指针,static成员函数中不能访问非static数据成员,也不能调用非static成员函数
指向成员的指针
类内部的成员是没有地址的,只有把成员在类中的偏移和具体对象的起始地址结合在一起才能得到实际的地址。使用指向数据成员的指针的语法应该如下:对象. 指向成员的指针,对象指针 -> 指向成员的指针**
定义指向数据成员的指针:*成员类型 类名字::指向成员的指针;
成员函数的指针:*返回类型 (类名::指向成员函数的指针)(参数表);