1 成员变量除了静态成员不能再定义类时初始化。
2 因为只有当一个类的类体已经完整时 它才被视为已经被定义 所以一个类不能有自身
类型的数据成员 但是 当一个类的类头被看到时 它就被视为已经被声明了 所以一个类
可以用指向自身类型的指针或引用作为数据成员 。
3 只有被声明为const 的成员函数才能被一个const 类对象调用 关键字const 被放在成员
函数的参数表和函数体之间 对于在类体之外定义的const 成员函数 我们必须在它的定义
和声明中同时指定关键字const
4 为了允许修改一个类的数据成员 即使它是一个const 对象的数据成员 我们也可以把
该数据成员声明为mutable 易变的 mutable 数据成员永远不会是const 成员 即使它是
一个const 对象的数据成员 mutable 成员总可以被更新 即使是在一个const 成员函数中
为把一个成员声明为mutable 数据成员 我们必须把关键字mutable 放在类成员表中的数据成
员声明之前 .
5 与全局对象一样 对于静态数据成员 在程序中也只能提供一个定义 这意味着 静态
数据成员的初始化不应该被放在头文件中 而应该放在含有类的非inline 函数定义的文件中
6 作为特例 有序型的const 静态数据成员可以在类体中用一常量值初始化 例如 如果
决定用一个字符数组而不是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";
在类体内初始化一个const 静态数据成员时 该成员必须仍然要被定义在类定义之外
但是 因为这个静态数据成员的初始值是在类体中指定的 所以在类定义之外的定义不能指定初始值
7 静态数据成员的 惟一性 本质 独立于类的任何对象而存在的惟一实例 使它能够
以独特的方式被使用 这些方式对于非static 数据成员来说是非法的
1) 静态数据成员的类型可以是其所属类 而非static 数据成员只能被声明为该类的对象
的指针或引用 例如
class Bar {
public:
// ...
private:
static Bar mem1; // ok
Bar *mem2; // ok
Bar mem3; // 错误
};
2 ) 静态数据成员可以被作为类成员函数的缺省实参 而非static 成员不能 例如
extern int var;
class Foo {
private:
int var;
static int stcvar;
public:
// 错误: 被解析为非 static 的 Foo::var
// 没有相关的类对象
int mem1( int = var );
// ok: 解析为 static 的 Foo::stcvar
// 无需相关的类对象
int mem2( int = stcvar );
// ok: int var 的全局实例
int mem3( int = ::var );
};
8 静态成员函数
class Account {
public:
static void raiseInterest( double incr );
static double interest() { return _interestRate; }
private:
static double _interestRate;
};
inline void Account::raiseInterest( double incr )
{
_interestRate += incr;
}
静态成员函数的声明除了在类体中的函数声明前加上关键字static 以及不能声明为
const 或volatile 之外 与非静态成员函数相同 出现在类体外的函数定义不能指定关键字
static
静态成员函数没有this 指针 因此在静态成员函数中隐式或显式地引用这个指针都将导
致编译时刻错误 试图访问隐式引用this 指针的非静态数据成员也会导致编译时刻错误 例
如 前面给出的成员函数dailyReturn()就不能被声明为静态成员函数 因为它访问了非静态
数据成员amount
我们可以用成员访问操作符点 . 和箭头 -> 为一个类对象或指向类对象的指针调用
静态成员函数 也可以用限定修饰名直接访问或调用静态成员函数 而无需声明类对象 下
面的小程序说明了静态类成员的用法
#include <iostream>
#include "account.h"
bool limitTest( double limit )
{
// 还没有定义 Account 类对象
// ok: 调用 static 成员函数
return limit <= Account::interest();
}
int main() {
double limit = 0.05;
if ( limitTest( limit ) )
{
// static 类成员的指针被声明为普通指针
void (*psf)(double) = &Account::raiseInterest;
psf( 0.0025 );
}
Account ac1( 5000, "Asterix" );
Account ac2( 10000, "Obelix" );
if ( compareRevenue( ac1, &ac2 ) > 0 )
cout << ac1.owner()
<< " is richer than "
<< ac2.owner() << "\n";
else
cout << ac1.owner()
<< " is poorer than "
<< ac2.owner() << "\n";
return 0;
}
9 成员函数有一个非成员函数不具有的属性——它的类 its
class 指向成员函数的指针必须与向其赋值的函数类型匹配 不是两个而是三个方面都要
匹配 1 参数的类型和个数 2 返回类型 3 它所属的类类型
类成员的指针必须总是通过特定的对象或指向该类类型的对象的指针来访问 我们通过
使用两个指向成员操作符的指针 针对类对象和引用的.* 以及针对指向类对象的指针的->*
来做到这一点 例如 如下所示 我们通过成员函数的指针调用成员函数
int (Screen::*pmfi)() = &Screen::height;
Screen& (Screen::*pmfS)( const Screen& ) = &Screen::copy;
Screen myScreen, *bufScreen;
// 直接调用成员函数
if ( myScreen.height() == bufScreen->height() )
bufScreen->copy( myScreen );
// 通过成员指针的等价调用
if ( (myScreen.*pmfi)() == (bufScreen->*pmfi)() )
(bufScreen->*pmfS)( myScreen );
静态类成员是属于该类的全局对象和函数 它们的指针是普通指针 请记住静态成员函数没有this 指针