文章目录
- 友元
- 内部类
- 内部类是外部类的天生友元
- 匿名对象
- 匿名对象的特性
友元
-
友元函数
重载operator<< 输出自定义类型
比如日期类的这个重载,就是解决类外访问私有变量的例子,设计成了友元函数。
说明:
友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰 (没有this指针,无法修饰) -
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员
用法:
class Time
{
friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:
Time(int hour = 0, int minute = 0, int second = 0)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类
- 问题:sizeof(A) = ?
回答:sizeof( A ) = 4
因为B在A的内部,其实他们之间没什么关系,只不过是B这个类型定义在A的类域里,没有B的实例化对象不占空间,类是图纸,如果A的成员变量里面 有个 B的实例化对象,那就占空间了。
static int k; 在静态区里,也不占空间。
class B 受访问限定符的控制,你可以公开权限,突破A类域生成B对象,如果是私有权限那么创建不了B对象
形象化:就是A是一个建筑图纸,那么B就是A图纸里面附赠的一份图纸
内部类是外部类的天生友元
匿名对象
例子1
A() 也可以这么写
例子2
这里面Solution().Sum_Solution(20)
我看了一开始也觉得奇怪,但是如果不加只剩类型,Solution.Sum_Solution(20)肯定无法调用
所以要加括号表明 是匿名对象
错误写法(不加括号):
这里又回溯回之前 类创建对象时为什么不加括号的问题:
原因:默认构造初始化对象 不能写成 Solution s1();的原因是 无法区分是函数还是初始化对象
匿名对象的特性
匿名对象生命周期在当前行
用引用强行续命,延长了生命周期在当前局部域
匿名对象具有常性(和临时空间一样具有常性)
类比
函数传值返回,如果返回的对象很大,那么它所保存在的临时空间是在哪里呢?
答:返回对象时内置类型时,一般都是通过寄存器来带回返回值的,返回对象如果时较大的对象时,一般会在主调函数的栈帧中开辟一块空间,然后把这块空间的地址,隐式传递给被调函数,在被调函数中通过地址找到主调函数中预留的空间,将返回值直接保存到主调函数的。
具体可以参考《程序员的自我修养》一书的第10章。