类的特殊成员

1.静态成员

2.友元

3.常量成员

静态成员

静态成员在类中分为静态数据成员和静态函数成员

静态数据成员

静态数据成员的创建方式如下:

1
2
3
4
5
6
7
class A{
public:
static int a;

}
//注意初始化格式
int A::a=5;//只能通过类外初始化或者类内公有函数初始化。

说明:

①静态数据成员作用于类内,存储在内存的静态全局区上,所以它的生命周期的开始早于主函数。

②静态数据成员无法在定义时初始化,只能通过类外初始化或者类内公有函数初始化。(有资料说能在类内重新赋值,我不理解)

③静态数据成员属于类,不属于对象,但是可以公有属性的静态数据成员可以被对象在类外访问。

④静态数据成员生命开始早于对象,当然可以被类内其他成员函数使用。(得符合访问属性)

静态函数成员

静态数据成员的创建方式如下:

1
2
3
4
5
6
7
8
class A{
public:
static int a;
static void func();
}
void A::func(){
//只能使用静态数据成员、局部变量、形参等等,不能使用类内其他数据成员或成员函数
};

①静态函数成员的作用域和生命周期与静态数据成员一致。

②静态函数成员可以在类内定义,也可以在类外定义。

③静态函数成员就相当于普通函数,只不过能够使用静态数据成员罢了。

④静态函数成员生命开始早于对象,当然可以被类内其他成员函数使用。(得符合访问属性)

软件设计模式——单例模式

单例模式,顾名思义就是只能实例化一个对象的模式

方法:

①私有化(private)构造函数与拷贝构造,防止类外创建对象的可能。

②在类内私有访问区域创建一个静态对象(为什么是静态?因为只有静态对象才可以在类内被创建啊),可以通过指针,也可以直接实例化(这样的话后续使用要通过引用)。

③提供一个静态的公有函数区获取这个私有对象。并且因为是静态对象,内存的静态存储区,生命周期贯穿整个程序,以后每次调用的就都会是这个对象,实现单例。

下面是一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Box{
private:
Box(){};
Box(const Box& box){};
static Box* p_box;

public:
static Box* get_box_ptr();//类内定义会被内联吗?
void speak(){
cout<<"ok"<<endl;
}
};
Box* Box::p_box=new Box;
Box* Box::get_box_ptr(){

return p_box;
}
int main(){
Box* p=Box::get_box_ptr();//使用p指针获取对象
p->speak();
return 0;
}

友元

友元分为友元函数和友元类,友元的作用就是打破类的封装

友元函数

友元函数就是一个普通函数,可以访问其已经声明为友元的类中的所以成员,包括静态(构造/析构等不行)

声明方法:(声明的位置没有限制在类的花括号内就可以

1
2
3
4
5
6
class A{
...
friend void func(A& a);//要传对象进去,不然无法操作,引用与否自己决定。

...
}

友元函数要想同时无限制的访问更多类,就得增加函数参数,并且在那些类中声明友元。

友元类

友元函数就是一个普通类,可以访问其已经声明为友元的类中的所以成员,包括静态(构造/析构等不行)

声明方法与友元函数一致。

**注意:**

友元的特性:①单方向

​ ②不传递

​ ③不继承

常量成员

类的常量成员包括:常量数据成员、常量函数成员、常量对象。

常量数据成员

在数据成员前加const限定符,常量数据成员不能被修改,且初始化有要求,只能用成员初始化列表的方式

1
2
3
4
5
6
7
8
9
10
class A{
public:
const int a;
A(int val):a(val);
}
int main(){

A a(1);
return 0;
}

常量函数成员

常量函数成员声明方法:

1
2
3
4
class A{
public:
void getnum()const;
}

常量函数成员就是一个不能改变所在对象数据成员函数。这是因为语法限制this指针不能使用,别的都可以。

常量对象:

常量对象不能通过接口改变对象内的数据**。

所以编译器不允许常量对象调用普通成员函数,只能调用常量成员函数。

常量对象内的数据可以被友元改变吗?

:不能,因为友元函数需要传入对象作为参数,所以常量对象传入时,友元的参数类型必须与之相匹配,也就是const student(以student为例子),那么自然就不能更改,因为是const类型的对象。