类定义中除了一般指定访问权限的成员,还可以定义各种特殊用途的成员。
常成员:常数据成员、常成员函数、常对象
静态成员:静态数据成员、静态成员函数
友元:友元函数、友元类
1.常数据成员:
在类中定义的不能修改其值的一些数据成员,
类似于常变量,虽然是变量,也有自己的地址,但是一经赋初值,便不能再被修改。
适用于类中定义一些初始化之后不希望被修改的数据成员。
常数据成员表示它在某个对象生存期内是常量, 即在对象生 成时给出常量值,在对象生存期内其值不可改变。而对于整 个类而言,不同的对象其常数据成员的值可以不同。 定义方法:const 类型名 变量名;
类中的常数据成员只能通过构造函数的参数初始化表进行初始化,任何其他函数都不能对该成员赋值。
由构造函数直接用常量初始化常数据成员
#include<iostream>
using namespace std;
class Mclass
{
public :
int k;
const int M; // 说明常数据成员
Mclass() : M(5) { } // 用初始化列表对常数据成员赋值 , // 这样使得每个对象都有相同的 M 值
void testFun()
{
//M++; // 错误,不能在成员函数中修改常数据成员
k++; // 可以修改一般数据成员
}
} ;
int main()
{
Mclass t1, t2;
t1.k=100;
//t1.M=123; // 错误,不能在类外修改常数据成员
cout<<"t1.k="<<t1.k<<'\t'<<"t1.M="<<t1.M<<endl;
t2.k=200; t2.testFun();
cout<<"&t1.M="<<&t1.M<<endl;
cout<<"t2.k="<<t2.k<<'\t'<<"t2.M="<<t2.M<<endl;
cout<<"&t2.M="<<&t2.M<<endl;
}
输出
t1.k=100 t1.M=5
&t1.M=0x6ffe04
t2.k=201 t2.M=5
&t2.M=0x6ffdf4
不能在类声明中初始化常数据成员。以下用法是错误的:
class A
{
const int SIZE = 100; // 错误,企图在类声明中初始化常数据成员
int array[SIZE]; // 错误,未知的 SIZE
};
用带参数的构造函数初始化常数据成员
#include<iostream>
#include<cstring>
using namespace std;
struct Date { int year, month, day ; }; // 结构
class Student
{
public:
Student (int y,int m,int d, int num=0, char *pname="no name");
void PrintStudent( ) const; // 常成员函数 这个成员函数不会修改数据成员的值
private:
const int code; // 常数据成员
char name[20];
Date birthday; // 结构数据成员
};
void Student::PrintStudent( ) const
{
cout<<"序号:"<<code<<"\t姓名:"<<name<<"\t"<<"出生日期:" <<birthday.year<<"-"<<birthday.month <<"-"<<birthday.day; cout<<endl;
}
//带参数构造函数完成数据成员初始化
Student::Student( int y, int m, int d, int num, char *pname ) : code( num )
// 这样使得每个对象可以有不同的 code 值
{
strcpy(name, pname);
birthday.year=y;
birthday.month=m;
birthday.day=d;
}
int main()
{
Student stu1( 1990, 3, 21, 1001, "陈春“ );
stu1.PrintStudent();
Student stu2(1985, 10, 1, 1002, "张庆华“ );
stu2.PrintStudent();
}
输出
序号:1001 姓名:陈春 出生日期:1990-3-21
序号:1002 姓名:张庆华 出生日期:1985-10-1
2.常成员函数
#include<iostream>
using namespace std ;
class Simple
{
int x, y ;
void constFun ( ) const
{ x ++ ; y ++ ; } //常成员函数 修改数据成员非法, 编译会报错
};
void printXY() { cout << x << "," << y << endl ;
} ;
void constFun ( ) const
{ /x ++ ; y ++ ;/ } //常成员函数 修改数据成员非法
常成员函数的使用
#include <iostream>
using namespace std;
class Cone
{
public:
Cone(int a,int b){x=a;y=b;}
void print()
{
cout<<"没有使用常量成员函数"<<endl;
cout<<x+y<<endl;
}
void print() const //const参与函数的重载
{ cout<<"使用了常成员函数"<<endl;
cout<<x+y<<endl; }
private:
int x, y;
};
void main()
{
Cone one(3,4);
one.print();
const Cone two(3,4);
two.print();
}
输出
没有使用常量成员函数
7
使用了常成员函数
7
常对象two只能调用它的常 成员函数void print( ) const 、 静态成员函数、构造函数 (具有公有访问权限)
3.常对象
常对象测试
#include<iostream>
using namespace std;
class T_class
{
public:
int a, b;
T_class( int i, int j ) { a=i; b=j; }
} ;
int main()
{
const T_class t1( 1, 2 );
T_class t2( 3, 4 );
//t1.a=5; //不允许更改常对象的数据成员的值
//t1.b=6; //不允许更改常对象的数据成员的值
t2.a=7;
t2.b=8;
cout<<"t1.a="<<t1.a<<'\t'<<"t1.b="<<t1.b<<endl;
cout<<"t2.a="<<t2.a<<'\t'<<"t2.b="<<t2.b<<endl;
}
t1.a=1 t1.b=2
t2.a=7 t2.b=8