目录
友元函数:
友元函数不能用const修饰
原因:友元函数并不是类的成员函数,类的成员函数中有this指针,this指针才需要被const修饰。
友元函数可以在类定义的任意位置声明:
友元类
class Time
{
friend class Date;
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 SetTimeDate(int hour, int minute, int second)
{
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
表示Date是Time的友元类,我们在类Time中可以访问Date类的私有的成员变量和共有的成员函数。
内部类(了解)
匿名对象:
class A
{
public:
A(int a = 1)
:_a(a)
{
cout << "构造函数" << endl;
}
~A()
{
_a = 0;
cout << "析构函数" << endl;
}
private:
int _a;
};
int main()
{
//A aa1(1); //构造
//A aa2 = 2; //构造+拷贝构造
/*A aa3();*/ //错误 无法区分函数声明和创建对象
A();
A(3);
return 0;
}
匿名对象会调用并且匿名对象的作用域是所定义的这一行。
class Solution {
public:
int Sum_Solution(int n) {
return n;
}
};
int main()
{
//A aa1(1); //构造
//A aa2 = 2; //构造+拷贝构造
/*A aa3();*/ //错误 无法区分函数声明和创建对象
/*A();
A(3);*/
int ret=Solution().Sum_Solution;
return 0;
}
匿名对象的作用是我们不需要创建类对象就可以调用成员函数。
并且我们在传递返回值时也可以使用匿名对象:
A F()
{
return A(10);
}
等价于构造加上返回。
编译器优化:
优化场景1
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "构造函数" << endl;
}
A(const A&aa)
:_a(aa._a)
{
cout << "拷贝构造" << endl;
}
A&operator=(const A&aa)
{
cout << "赋值重载" << endl;
if (this != &aa)
{
_a = aa._a;
}
return *this;
}
~A()
{
_a = 0;
cout << "析构函数" << endl;
}
private:
int _a;
};
int main()
{
A aa1 = 1;//构造+拷贝构造直接优化为构造
}
优化场景2:
int main()
{
//A aa1 = 1;//构造+拷贝构造直接优化为构造
A aa1;
f1(aa1);//构造+拷贝构造
}
优化:
void f1(A aa)
{
}
int main()
{
//A aa1 = 1;//构造+拷贝构造直接优化为构造
//A aa1;
//f1(aa1);//构造+拷贝构造
f1(A(1));
}
直接优化成构造函数。
无法优化的场景:
void f1(const A& aa)
{
}
int main()
{
//A aa1 = 1;//构造+拷贝构造直接优化为构造
//A aa1;
//f1(aa1);//构造+拷贝构造
f1(A(1));
}
匿名对象具有常性,所以用const修饰,传引用传参不会发生拷贝构造,所以只有一个构造:
优化场景3
A f()
{
A aa;
return aa;
}
int main()
{
//A aa1 = 1;//构造+拷贝构造直接优化为构造
//A aa1;
//f1(aa1);//构造+拷贝构造
//f1(A(1));
A ret=f();//构造+拷贝构造+拷贝构造
}
构造+拷贝构造+拷贝构造优化为构造+拷贝构造。
这样写无法优化,这里是赋值。
优化场景4:
A f()
{
return A(3);
}
int main()
{
//A aa1 = 1;//构造+拷贝构造直接优化为构造
//A aa1;
//f1(aa1);//构造+拷贝构造
//f1(A(1));
//A ret;//构造+拷贝构造+拷贝构造
//ret = f();
A ret = f();
}
直接构造:
如何触发编译器优化?
答:能用匿名对象就用匿名对象。