文章目录
- 🌈 Ⅰ const 修饰 this 指针
- 🌈 Ⅱ static 静态成员
- 🌈 Ⅲ friend 友元
- 1. 友元函数
- 2. 友元类
- 🌈 Ⅳ 内部类
- 🌈 Ⅴ 匿名对象
🌈 Ⅰ 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;
}