友元和优化

目录

友元函数:

 友元函数不能用const修饰

友元函数可以在类定义的任意位置声明:

 友元类

内部类(了解)

匿名对象:

 ​编辑

编译器优化:

优化场景1

优化场景2:

 无法优化的场景:

优化场景3

优化场景4:

 


友元函数:

友元和优化_第1张图片

 友元函数不能用const修饰

原因:友元函数并不是类的成员函数,类的成员函数中有this指针,this指针才需要被const修饰。

友元函数可以在类定义的任意位置声明:

友元和优化_第2张图片

 友元和优化_第3张图片

 友元类

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类的私有的成员变量和共有的成员函数。

友元和优化_第4张图片

内部类(了解)

友元和优化_第5张图片

 友元和优化_第6张图片

匿名对象:

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; 
}

 友元和优化_第7张图片

匿名对象会调用并且匿名对象的作用域是所定义的这一行。

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);//构造+拷贝构造
}

友元和优化_第8张图片

优化:

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();//构造+拷贝构造+拷贝构造
}

友元和优化_第9张图片

构造+拷贝构造+拷贝构造优化为构造+拷贝构造。

 友元和优化_第10张图片

 友元和优化_第11张图片

 

这样写无法优化,这里是赋值。

 友元和优化_第12张图片

优化场景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();
}

直接构造:

 

如何触发编译器优化?

答:能用匿名对象就用匿名对象。

你可能感兴趣的:(开发语言)