在前三篇博客中,我们已经简要介绍类与对象中的大部分内容,这也是最后一篇介绍类与对象的博客,就让我们以四个知识点收尾。
1.初始化列表------定义+初始化成员变量
我们已经认识过多种构造函数,一般在构造函数中给变量赋予默认值,或者给变量缺省值,我们已经学过这两种初始化方式,而初始化列表是最常用、最推荐使用的方式。
来看初始化列表如何初始化成员变量:
Date (int year, int month, int day)
:_year(year),_month(month),_day(day)
{
}
1.只能写在构造函数后面(每个构造函数都有初始化列表),以冒号开始,以逗号分隔,依次是成员变量,括号里是它的初始值或表达式。
2.只能初始化一次,按类中声明顺序初始化,而不是在列表出现的顺序。
3.类中成员变量并不是一定要出现在列表中。
注意:
有三种类型要额外记住:
①const修饰的变量,只能在列表处初始化,因为初始化就是定义的地方,而const 修饰的变量又不可修改,所以只能在列表处初始化。
②引用型变量,同样,只能在定义处赋值,因此只能在列表初始化。
③没有默认构造函数可用的自定义类型,这种类型就无法通过列表初始化。
对比:
现在,要初始化一个日期类对象,我们已经掌握了三种方法:
①成员变量声明处赋给成员变量某值(不赋值),用编译器自带默认构造函数,生成的是赋给的值(随机值)。
②用构造函数参数缺省值给成员变量赋值。
③初始化列表,成员变量定义+初始化的位置。
对于这三种方法而言,优先级③>②>①,初始化列表是定义及初始化的地方,成员变量先经过初始化列表,按所传参数给变量赋值,如果缺省,用缺省值补上。
eg:
class Date
{
public:
Date (int year,int month=1,int day=1)
:_year(year),_month(month),_day(day)
{
}
void print()
{
cout<<_year<<"/"<<_month<<"/"<<_day<<endl;
}
private:
int _year;
int _month;
int _day;
}
int main ()
{
Date A(2025,10);
A.print();
}
2.static 关键字
我们知道static 修饰的局部变量只能被初始化一次(可以加减运算,只能初始化一次),生命周期是全局。 如下count 只有一开始是0
void function() {
static int count = 0; // 局部静态变量
count++;
std::cout << "Function has been called " << count << " times." << std::endl;
}
如果把static 修饰成员变量,它就成为静态成员变量,遵循:
1.类内声明,类外初始化。
2.不在类内存储,存放在静态区。
3.被所有该类的对象所共享。
static 修饰成员函数,成为静态成员函数。
静态成员函数属于类本身,而不是类的某个特定对象。它们不能访问类的非静态成员变量以及非静态成员函数。其与非静态成员函数不同的是,没有this指针。
而非静态成员函数可以访问静态的成员变量及成员函数。
3.friend 友元
友元函数:
C++引入访问限制符,使得外部不能直接改变成员变量,而是要通过接口来访问。friend 友元提供了便利的通道,函数声明写在类中,前面再加上 friend ,就允许该函数访问类中的成员变量(不受访问限制符约束),我们称它为友元函数。一个函数还可以成为多个类的友元函数。
eg:
前面我们写过重载<< 和 >>运算符函数就很适合写成友元函数。
ostream& operator<<(ostream& out,const Date& d)
{
out << d._year<<"/" << d._month << "/" << d._day ;
return out;
}
istream& operator>>(istream& in, Date& d) //不能加const了
{
cout << "请输入年月日:>" << endl;
in >> d._year >> d._month >> d._day;
return in;
}
友元类:
假令②成为①的友元类,②的成员函数就都是①的友元函数。
但友元类不能传递,a是b的友元类,b是c的友元类,但a不是c的友元类。
总的来讲,友元方便外部快速访问成员变量,但增加了耦合度,且破坏了封装,不宜多用。
4.内部类
在C语言struct 结构体可以嵌套,C++中的类也是可以的。内部类通常指的是嵌套类,它定义在另一个类的内部。嵌套类可以访问外部类的成员,包括私有成员。
eg:
#include<iostream>
using namespace std;
class A
{
public: // B是A的内部类
class B // B默认是A的友元,可以访问A的私有成员变量
{
public:
void display(const A& aa)
{
cout << aa.ked << endl;
}
};
private:
int ked=2077;
};
int main()
{
A x;
A::B y;
y.display(x);
}
注意B类对象是怎么构造出来的,注明A::域。
完结
类与对象的内容介绍到这里,但知识的掌握还需要实践检验,动手敲一遍才能发现自己的问题。
如果你有更好的见解或指正,欢迎在评论区讨论。