C++中的class
用class qxz{ };
定义一个类,其中private:
以下的每一行都是私有成员,而public:
以下的每一行都是公有成员(两者可以反复交叉出现多次)。私有成员只能被自己类中的成员函数访问,而公有成员可以被外部访问。
一般只把非常简单的成员函数在类定义中写出(这样写出的默认为内联函数),对于比较复杂的函数一般只在类定义中写出函数原型,而将实现放在外面(函数名前加“类名双冒号”,比如void qxz::f(){}
)。
C++中一个类的成员函数在内存中只有一个副本,无论有多少该类的对象。在某个成员函数进行的过程中,程序应当知道正在被运行的成员函数究竟是哪个对象的成员函数。因此,C++的每个成员函数在被运行时都隐藏着一个指针变量this
,函数中使用的成员变量a
实际上是(*this).a
(即this->a
)。由于编译器会帮我们自动补全this
,因此一般写代码不需要加上this->
来访问成员变量。但如果需要访问这个对象整体,就可以通过this
来访问。
在一个类的对象被建立的时候系统会自动调用构造函数(假如没有写任何构造函数则编译器会自动生成一个默认构造函数,给每个变量赋随机值)。构造函数的格式为(假设定义在class大括号之外)qxz::qxz(int x = 0, int y = 1){ a = x; b = y; }
。构造函数是没有返回值的,不能在函数名以前写任何返回类型;构造函数的函数名和类型名完全相同;构造函数有一个参数表,在定义具体对象的时候写qxz v(2,3)
;如果直接写qxz v
,则按照构造函数形参表中等号后面的默认赋值进行赋值,如果写了括号则视而不见。不写默认赋值而直接用qxz v
定义变量,同时没有参数为空的构造函数时,程序会报错。还可以直接使用初始化列表qxz::qxz(int x, int y): a(x), b(y) {}
。
可以直接用一个定义过的类的对象来初始化一个对象,这时就会用到拷贝构造函数。格式为qxz(const qxz &B){}
。如果没有定义,则编译器会自动生成一个默认的拷贝构造函数,默认拷贝构造函数会一模一样地赋值初始化。拷贝构造函数不仅在用括号定义新对象时会起作用qxz tmp_1(tmp_2)
,实际上在每一次“赋值的等号”中都会起作用,比如tmp_1 = tmp_2
时。由于形参实际上是局部变量+赋初始值,因此函数调用时也会使用拷贝构造函数。函数返回值也是同理。
在类的对象消亡前系统会自动调用类的析构函数。析构函数完成一些善后工作,其没有返回类型也没有参数,函数名为波浪线+类名。格式为~qxz() {...}
,例如写析构函数在对象消亡前自动回收空间。
数据成员可以用const
定义为常量。常量仅表示当前类的对象生命周期内其值不能被修改,不同对象的常量可以不同。常量只能初始化,不能赋值,因此必须在构造函数中设定。类的成员函数可以设定为常量成员函数,代码中在函数头后加上const
,即void fff() const {}
。函数设定为常量之后编译器不允许该函数修改这个类的所有数据成员,该函数不能调用会修改数据成员的成员函数。任何不修改数据成员的函数都应该声明为const
类型。
类的数据成员可以声明为“静态”。静态的数据成员可以理解为一个全局变量,但是由于它可以被设定为private
,具有保护数据的作用。声明静态数据成员在类型前加关键字static
,例如static int a;
。无论有多少具体的对象,静态成员的空间只有一个,这个空间不是在定义新的对象时申请的,而是在类被实现的时候被分配的,在实现时必须为静态成员赋值:int qxz::a = 1;
。由于静态数据成员是“全局”的,可以通过x.a
来访问,也可以直接通过qxz::a
来访问。同样的,也有静态成员函数,它只能访问静态数据成员或者其它的静态成员函数。同样的,通过在函数头前加static
来声明。由于静态成员函数没有this
指针,它不能访问具体的对象。但它能够在任何对象被建立以前操作静态变量,例如用它来完成静态成员的初始化工作。静态数据成员可以设定为常量,声明用static const
。
类的外部不能访问私有成员,但为了提高效率,可以允许某些全局函数、其他类的所有成员函数、或者其他类的某一成员访问该类的私有成员,以上三者分别称为类A的友元函数、友元类、友元成员函数,统称友元。把全局函数void f();
声明为A的友元函数,在A中写friend void f();
;把某个类B(的所有成员)声明为A的友元函数,在A中写friend class B
;把类B中的某个函数void g()
声明为A的友元函数,在A中写friend void B::g();
。一般把友元声明写在一起,放在整个类代码的顶端或末尾。友元不具有对称性和传递性。由于它破坏了类的封装,是一种“开后门”行为,要谨慎使用。