1.为什么使用友元?
A = B * 2.75
A = B.operator * (2.75)
B是类对象,2.75是double类型,在这个式子中,B必须在左侧,因为B.operator()实际上式B对象的函数调用。
而通过非成员函数,非成员函数不是对象调用的,它使用的所有值都是显式参数,所以能匹配成如下函数式:
A = operator *(2.75, B);
其中,一种可以访问类的私有成员的非成员函数叫做友元函数。
2.创建友元
#include <iostream>
#include <ostream>
class Time {
private: int hours;
int minutes;
public: friend Time operator*(double m, const Time& t); //友元,不是成员函数,但与成员函数访问权限相同。
Time();
Time(int x, int y);
friend void operator<<(std::ostream& os, const Time& t)
{
os << t.hours << "hours, " << t.minutes << "minutes";
}
};
Time operator*(double m, const Time& t)
{
Time result;
long totalminutes = t.hours * 60 * m + t.minutes * m;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
Time::Time() {
hours = 0;
minutes = 0;
}
Time::Time(int x, int y)
{
hours = x;
minutes = y;
}
int main() {
Time half_one_hour(0, 30);
Time A;
A = 2 * half_one_hour;
std::cout << A;
}
1)类声明中定义: friend Time operator*(double m, const Time &t);
不能使用成员运算符来调用,但是与成员函数的访问权限相同,即可以在友元函数定义中访问私有函数。
2)编写函数定义:Time operator*(double m, const Time & t){}
由于不是成员函数,所以不要使用Time::限定符;
3)因为只有在成员函数和友元函数中访问私有函数,所以想要打印私有函数,需要定义<<的友元函数,如上。
4)将<<友元函数的返回值设为ostream &,就可以实现cout<<T1<<T2这种级联。
5).如下:
Time operator+(const Time& t) const; //1
friend Time operator+(const Time& t1, const Time& t2); //2
对于1式,一个操作数通过this指针隐式传递,另一个操作数通过函数参数显示传递。而二式,两个操作数都以参数显示传递。
类的自动转换
1.c++自动类型转换:将一个标准型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,将自动类型转换。
如下:
long n1 = 100;
int n2 = n1;
n1将自动被转换成int再赋值给n2。
例将数值赋给指针,因为指针和整数是完全不同的,例如不能计算指针的平方,但可以使用强制类型转换,如下:
int* p = (int*)10;
2.隐式转换函数:
如下:
class MyClass {
public:
MyClass(int value) : value(value) {}
// 隐式转换函数,允许从 MyClass 转换为 int
operator int() const {
return value;
}
private:
int value;
};
int main() {
MyClass obj(42);
int x = obj; // 隐式转换为 int
std::cout << "The value is: " << x << std::endl; // 输出: The value is: 42
return 0;
}
MyClass obj (42)创建一个MyClass对象,并将value赋值为42。
在执行int x = obj;时满足转换没有二义性,确认将一个对象转换成int,因此会自动调用隐式转换函数int(),最后x被赋值为42。
可以使用explicit防止隐式转换。