C++ 4 引用、指针、常量、静态、友元
引用 &
int a;
int & b = a;
int & c = b;
int * p = & b;
int * & q = p;
int a = 3 ;
const int & b = a;
int & b = a;
b = 5 ;
a = 5 ;
c = & a;
int & c = a;
void & d = 9 ;
int g[ 5 ] ;
int & f[ 5 ] = g;
void swap ( int & a, int & b) { }
void swap ( int * a, int * b) { }
void fun ( Time& T) { }
void fun ( Time* p) { }
swap ( i, j) ;
swap ( & i, & j) ;
void fun ( T) ;
void fun ( p) ;
指针 *
① 指向对象的指针
Student stu, * p;
p = & stu;
p-> num = 100 ;
p-> data ( ) ;
( * p) . num = 100 ;
( * p) . data ( ) ;
stu. num = 100 ;
stu. data ( ) ;
② 指向对象数据成员的指针
int * p;
p = & stu. name;
cout<< * p<< endl;
③ 指向对象成员函数的指针
void ( Student: : * p) ( int , char ) ;
p = & Student: : fun
void ( Student: : * p) ( int , char ) = & Student: : fun;
( stu. * p) ( 99 , "A" ) ;
④ 指向普通函数的指针
void ( * p) ( int , char ) ;
p = fun;
( * p) ( 99 , "A" ) ;
⑤ 指向当前对象的 this 指针
stu. fun ( ) ;
this-> name
( * this) . name
常量 const
形式 含义 const float PI = 3.14;
常变量 Student const stu(01, "A");
常对象 const Student stu(01, "A");
常对象 const int name;
常数据成员 void show() const;
常成员函数 const int *p;
指向对象的常指针 const Student *p;
指向常变量的指针变量 const int *p;
指向常对象的指针变量 const Student &a = stu;
对象的常引用
① 常变量
const float PI = 3.141592653 ;
② 常对象
定义常对象时,必须同时进行初始化,之后不能再改变 只能调用其常成员函数,常成员函数是常对象的唯一对外接口
Student const stu ( 01 , "A" ) ;
const Student stu ( 01 , "A" ) ;
有时一定要修改常对象中某个数据成员的值 ( 如用于计数的变量count
) ,将其声明为mutable
mutable int count;
③ 常对象成员——常数据成员
常数据成员只能通过构造函数的参数初始化表 来进行初始化
const int name;
Student ( char n) : name ( n) { }
Student ( char n) ;
Student: : Student ( char n) : name ( n) { }
④ 常对象成员——常成员函数
只能引用本类的数据成员,且不能修改 不能调用另一个非const
成员函数
void show ( ) const ;
数据成员 非const
的普通成员函数 const
成员函数非const
的普通数据成员 可以引用,也可以改变值 可以引用,但不可以改变值 const
数据成员可以引用,但不可以改变值 可以引用,但不可以改变值 const
对象不允许 可以引用,但不可以改变值 不能调用另一个非const
成员函数
⑤ 指向对象的常指针
指针变量为常量,不能改变指向,指针变量始终指向一个对象
Student stu ( 01 , "A" ) ;
Student * const p;
p = & stu;
Student * const p = & stu;
⑥ 指向常变量的指针变量
指向常变量的指针 变量指向非常变量 ,不能通过该指针来改变其值,,但指针的指向可以改变用该指针访问期间,该变量具有常变量的特征
int a;
const int * p;
p = & a;
* p = 1 ;
a = 1 ;
指向常变量的指针 变量指向常变量 ,且常变量 只能用指向常变量的指针 指向它,不能通过该指针来改变其值,但指针的指向可以改变
const int a = 1 ;
const int * p;
p = & a;
const char b[ ] = "hello" ;
const char * q;
q = b;
若函数的形参是指向非const
变量的指针变量,实参只能用指向非const
变量的指针
形参 实参 合法否 改变指针所指向的变量的值 指向非const
变量的指针 非const
变量的地址 合法 可以 指向非const
变量的指针 const
变量的地址非法 —— 指向const
变量的指针 非const
变量的地址 合法 不可以 指向const
变量的指针 const
变量的地址合法 不可以
⑦ 指向常对象的指针变量
指向常对象的指针变量 指向常对象 ,不能通过该指针来改变其值,但指针的指向可以改变
const Student stu ( 01 , "A" ) ;
const Student * p;
p = & stu;
const Student * p = & stu;
( * p) . name = "B" ;
stu. name = "B" ;
指向常对象的指针变量 指向非常对象 ,不能通过该指针来改变其值,但指针的指向可以改变
Student stu ( 01 , "A" ) ;
const Student * p = & stu;
( * p) . name = "B" ;
stu. name = "B" ;
⑧ 对象的常引用
常用常指针和常引用作函数参数,可不必建立实参的拷贝
const Student & a = stu;
静态 static
① 静态数据成员
静态数据成员在内存中只占用一份空间,并不是每个对象都分别为它保存一份空间 静态数据成员对所有对象都是一样的 静态数据成员只能在类体外初始化 ,不能用参数初始化表 对其进行初始化,若未初始化,系统自动赋值为 0
static int height;
int Box: : height = 10 ;
Box box1;
cout<< Box: : height<< endl;
cout<< box1. height<< endl;
② 静态成员函数
静态成员函数不是为了对象之间的沟通,而是为了处理静态数据成员 静态成员函数不属于某一对象,所以没有this
指针,因此不能访问本类中的非静态成员,可以直接引用本类的静态成员 若要访问非静态成员:box1.height
static int fun ( ) ;
int Box: : fun ( ) { . . . }
Box box1;
cout<< Box: : fun<< endl;
cout<< box1. fun<< endl;
友元 friend
① 友元函数
友元函数可以访问这个类中的私有成员 必须作为友元函数的重载运算符函数:<<
>>
类型转换运算符
一般将双目运算符重载为友元函数
将普通函数声明为友元函数
其不是类的成员函数,没有this
指针,因此在引用私有数据成员时,必须加上对象名
friend void fun ( ) ;
void fun ( ) { }
将另一个类的成员函数声明为友元函数
class Date;
class Time{
public:
void display ( Date & ) ;
} ;
class Date{
public:
friend void Time: : display ( Date & ) ;
} ;
void Time: : display ( Date & d) { }
② 友元类
友元类可以访问本类所有成员 非双向,若 B 是 A 的友元,不等于 A 是 B 的友元 非传递,若 B 是 A 的友元,C 是 B 的友元,不等于 C 是 A 的友元
friend B;
参考资料
[1]谭浩强.C++面向对象程序设计(第2版)北京:清华大学出版社,2014.
C++ 1 基础知识 C++ 2 组合与继承 C++ 3 构造函数与析构函数 C++ 4 引用、指针、常量、静态、友元 C++ 5 多态性 C++ 6 输入输出流