1。类的数据成员
数据成员的声明开起来很像在块域或名字空间域中的变量声明。但是,除了静态(static)数据成员外,数据成员不能在类体内被显示地初始化(在windows vc6.0上实验,结果是都不能在类体内初始化静态数据成员和const静态数据成员)。例如:
class First{
int memi = 0; // error
double memd = 0.0; //error
};
类的数据成员通过类的构造函数进行初始化。
2。成员访问
访问限定:
1)public member
在程序的任何地方都可以被访问实行信息隐藏的类将其public 成员限制在成员函数上这种函数定义了可以被一般程序用来操纵该类类
型对象的操作。
2)private member
只能被成员函数和类的友元访问
3)protected member
对派生类derived class 就像public 成员一样,对其他程序则表现得像private
3。静态类成员
有时候某个特殊类类型的所有对象都需要访问一个全局对象。在这种情况下类的静态数据成员提供了一个更好的方案静态数据成员被当作该类
类型的全局对象对于非静态数据成员每个类对象都有自己的拷贝而静态数据成员对每个类类型只有一个拷贝静态数据成员只有一份由该类类型的
所有对象共享访问。
一般地静态数据成员在该类定义之外被初始化如同一个成员函数被定义在类定义之外一样在这种定义中的静态成员的名字必须被其类名限定修饰
与全局对象一样对于静态数据成员在程序中也只能提供一个定义,这意味着静态数据成员的初始化不应该被放在头文件中而应该放在含有类的非inline 函数定义的文件中。
静态成员例子:
static_class_member.h:
#include <iostream>
#include <string>
using namespace std;
class Account
{
Account(double amount,const string &owner);
string owner(){ return _owner;}
private:
static double _interestRate;
double _amount;
string _owner;
};
static_class_member.cpp:
#include "static_class_member.h"
double Account::_interestRate = 0.59;//注意:定义的时候没有带关键字static
3.1静态成员
作为特例有序型的const 静态数据成员可以在类体中用一常量值初始化 ///vc6.0中不支持,需要用emun
例如如果
决定用一个字符数组而不是string 来存储账户的姓名那么我们可以用int 型的const 数据成
员指定该数组的长度,如:
// 头文件
class Account {
// ...
private:
static const int nameSize = 16;
static const char name[nameSize];
};
// 文本文件
const int Account::nameSize; // 必需的成员定义
const char Account::name[nameSize] = "Savings Account“
3.2)静态成员变量的访问:
在类的成员函数中可以直接访问该类的静态数据成员而不必使用成员访问操作符
但是在非成员函数中我们必须以两种方式之一访问静态数据成员 . 和*
因为类静态数据成员只有一个拷贝所以它不一定要通过对象或指针来访问访问静态
数据成员的另一种方法是用被类名限定修饰的名字直接访问它
// 用限定修饰名访问静态成员
if ( Account:_interestRate < 0.05 )
3.3)静态数据成员的唯一性
1).静态数据成员的类型可以是其所属类,而非static数据成员只能被声明为该类的对象的指针或引用。例如:
class Bar{
public:
//....
private:
static Bar mem1; // ok;
Bar * mem2;//ok
Bar mem3; //error
2).静态数据成员可以被作为类的成员函数的缺省实参,而非static成员不能。例如:
extern int var;
class Foo {
private:
int var;
static int stcvar;
public:
int mem1(int = var); // error ,没有相关的类对象,不同的类对象var的值不同
int mem2(int = stcvar); //无需相关的类对象,stcvar的值都一样
int mem3(int =::var); // int var 的全局实例
};
4.静态成员函数
除了访问静态成员数据外,不访问其他成员数据的成员函数,可以定义为静态成员函数。
出现在类体外的函数定义不能指定关键字static。
静态成员函数没有this指针,因此在静态成员函数中隐式或显式地引用这个指针都将导致编译时刻错误。
5.指向类成员的指针
1)指向类数据成员的指针和类成员函数指针的声明都要求考虑类的类型。
如:
short Screen::*
2)指向short型的Screen类的成员的指针的定义如下:
short Screen::*ps_Screen;
ps_Screen 可以用_height的地址初始化,如下:
short Screen::*ps_Screen = &Screen::_height;
3)定义一个成员函数指针需要指定函数返回类型、参数表和类。
例如,指向Screen成员函数并且能够引用成员函数height()和width()的指针类型如下:
int (Screen::*) ()
typedef int (Screen::*PTRFUN)();
PTRFUN pFun = &Screen::home;
6. 静态类成员的指针
静态类成员是属于该类的全局对象和函数。它的指针是普通指针。
class Account {
public:
static double interest(){return _interestRate;}
private:
static double _interestRate;
};
&_interestRate的类型为double *,而不是double Account::*
指向_interestRate的指针定义如下:
double Account::interest()
引用:*pd
指向interest()的指针类型是一个普通函数指针:
double (*)();
double (*pf)() = &Account::interest();
引用: (*pf)();
7。联合
union的成员可以被声明为公有、私有或保护的:
union TokenValue {
public:
char _cval;
private:
int priv;
};
int main() {
TokenValue tp;
tp._cval = '/n'; //ok;
tp.priv =10; //error;
}
union不能有静态数据成员或是引用成员。如果一个类类型定义了构造函数、析构函数或拷贝赋值操作符,则它不能成为union的成员类型。
union可以有成员函数,构造和析构函数
{
double *pd = &Account::_interestRate; //private 成员只能在成员函数和友元函数中才能用
}