🌈 Ⅰ const 修饰 this 指针
1. const 成员函数概念
- 将 const 修饰的 成员函数 称之为 const 成员函数,const 修饰类的成员函数,实际是修饰该成员函数隐含的 this 指针,表明在该成员函数中不能修改类的任何成员变量。
2. const 成员函数格式
[返回值类型] 函数名(形参列表) const
{
函数体
}
.3. const 成员函数示例
class date
{
public:
date(int year = 1, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
void Print() const
{
// const 修饰隐含的 this 指针,防止改变对象的内容
// 只想打印对象 d 内的值,不期望也不允许去改变
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
const date d(2024, 2, 8); // const 修饰的对象 d 的值不允许被改变
d.Print();
return 0;
}
4. const 成员函数特点
- const 对象 不能 调用非 const 成员函数,会放大 const 对象的权限。
- 非 const 对象 可以 调用 const 成员函数,将对象传给函数时,会缩小权限。
- 在 const 成员函数内 不能 调用其他的非 const 成员函数。
- 非 const 成员函数 可以 调用其他的 const 成员函数。
🌈 Ⅱ static 静态成员
1. static 静态成员概念
- 用 static 修饰的类的成员称为类的静态成员。
- 用 static 修饰ide成员变量称为静态成员变量;用 static 修饰的的成员函数称为静态成员函数。
- 静态成员变量只能在类外面进行初始化。
class date
{
public:
date(int month, int day)
{
_month = month;
_day = day;
}
private:
static int _year;
int _month;
int _day;
};
int date::_year = 2024; // _year 是静态成员变量,只能在类外初始化
int main()
{
date d(2, 8);
return 0;
}
static 静态成员特性
- 静态成员为所有类对象共享,不属于某个具体的对象,存放在静态区。
- 静态成员变量必须定义在类外,定义时不需要加上 static,类中的只是声明。
- 类的静态成员可以用类名::静态成员或对象.静态成员访问。
- 静态成员函数没有隐藏的this 指针,不能访问任何非静态成员。
- 静态成员也是类的成员,也受到访问限定符的限制。
🌈 Ⅲ friend 友元
- friend 友元提供了一种突破封装的方式,使得与某个类无关的其他类和函数能够访问该类的非公有成员。
1. 友元函数
- 在类内部对外部函数进行友元声明,使得外部函数能够访问类的非公有成员。
class date
{
public:
date(int year = 1, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
// 将外部函数 Display 声明成 date 类的朋友
friend void Display(const date& d);
private:
int _year;
int _month;
int _day;
};
void Display(const date& d)
{
// Display 函数是 date 类的朋友的话就能使用 date 类的私有成员了
printf("%d-%d-%d\n", d._year, d._month, d._day);
}
int main()
{
date d(2024, 2, 8);
Display(d);
return 0;
}
2. 友元类
- 使用方法和友元函数类似,现有 A、B 两个类,单方面将类 B 声明成类 A 的友元类的话,类 B 就能使用类 A 的非公有成员,而类 A 却不能使用类 B 的非公有成员。
class Time
{
public:
friend class Date; // Time 认为 Date 是它的朋友
// 但 Date 不认为 Time 是它的朋友,Time 无法使用 Date 的非公有成员
Time(int hour = 1, int minute = 1, int second = 1)
:_hour(hour)
,_minute(minute)
,_second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
// Date 没有对 Time 进行友元类声明
// Date 可以使用 Time 的非公有成员
void PrintTime(const Time& t)
{
printf("%d-%d-%d\n", t._hour, t._minute, t._second);
}
private:
int _year;
int _month;
int _day;
};
🌈 Ⅳ 内部类
内部类概念
- 顾名思义,定义在类内部的类。
- 内部类是一个独立的类,它不属于外部类。
- 内部类天生就是外部类的友元类
内部类特性
- 内部类可以定义在外部类的 public、protected、private 各个限定区域。
- 内部类可直接访问外部类的 static 成员。
- sizeof(外部类) 计算的是外部类的大小,和内部类没有任何关系。
内部类实例化方式
外部类::内部类 实例化的对象;
内部类示例
class A
{
public:
class B // B 天生就是 A 的友元类
{
public:
void Print(const A& a)
{
cout << a.h << k << endl;
// 内部类可直接访问外部类的 static 成员
}
};
private:
int h;
static int k;
};
int A::k = 1;
int main()
{
A::B b;
b.Print(A());
return 0;
}
🌈 Ⅴ 匿名对象
匿名对象概念
- 不用类来进行实例化对象然后用对象传参,而是直接使用类名进行传参。
- 在某些只是为了传个参数的地方可以使用。
- 匿名对象的生命周期只有它所在的那一行。
匿名对象示例
class A
{
public:
A(int a)
:_a(a)
{
cout << "A(int a)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
A(5); // 匿名对象存在的意义就是为了传一下参数,所以生命周期只有 1 行
// 等到了下一行会立马调用析构函数
return 0;
}