本次学习,知识点如下:
- 运算符重载
- 友元
- 重载
<<
运算符 - 类的自动转换和强制转换
- 类转换函数
运算符重载
- 运算符重载格式, 如下所示:
// op必现是有效的C++操作符,不能虚构一个新的操作符
operator op(args)
- 重载有限制。
- 重载的运算函数不必是类的成员函数,但至少有一个操作数时用户自定义的类型。
- 不能违背运算符的语法规则,不能修改运算符的优先级。
- 不能创建一个新的操作符
- 部分C++操作符不允许重载
友元
- 友元函数
- 友元类
- 友元成员函数
友元函数
- 声明友元函数方式,如下所示
class className(){
friend type method(args);
};
- 友元函数不是成员函数,所以实现友元函数时不能使用类作用域
::
,同时也不要再使用friend.。 - 尽管友元函数不是成员函数,但它具有和成员函数一样的权限,可以访问类对象的所有的成员数据,包括
private
声明的成员数据。 - 只有类声明可以决定哪一个函数是友元,因此类可以控制哪些函数可以访问。
- 重载运算符时,如果友元函数和类成员函数的参数一样,则友元函数和类成员函数只能选其一。
友元类
暂时不介绍,后续章节介绍
友元成员函数
暂时不介绍,后续章节介绍
重载<<
运算符
假如我们想有第使用cout
直接打印出我们的对象,如 cout<<student;
,
但我们不可能在cout类中添加友元函数,这样会破坏类库。这时,我们可以在Student中重载<<
,并将该成员函数声明为友元函数。实例如下:
//Student.h
#define GO2019_STUDENT_H
#include "string"
#include "iostream"
class Student{
private:
std::string mName;
int mAge;
public:
Student(Student &);
Student(std::string name);
Student(std::string name, int age);
int getAge(){
return mAge;
};
std::string getName(){
return mName;
}
friend std::ostream & operator<<(std::ostream & os, const Student & student);
};
#endif //GO2019_STUDENT_H
//Student.cpp
#include "Student.h"
#include "string"
Student::Student(std::string name, int age) : mName(name), mAge(age) {}
Student::Student(Student &student) {
mName = student.mName;
mAge = student.mAge;
}
Student::Student(std::string name) {
mName = name;
}
std::ostream & operator<<(std::ostream & os, const Student & student) {
os << "Name:" << student.mName << " Age:" << student.mAge;
return os;
}
// main实现
#include "Student.h"
#include "iostream"
int main() {
using namespace std;
Student student("hbx", 24);
cout << student;
return 0;
}
类的自动转换和强制转换
将其他类型转换为对象
- 只有一个参数的构造函数才能作为转换函数。
如Student hbx = "hh"
; 程序将调用Student(std::string)
构造函数创建一个临时Student对象,随后将采用逐成员方式将临时对象的内容复制到hbx
对象中。 - 可使用
explicit
关闭隐式转换,但仍然允许强制转换 - 隐藏转换存在二义性时,编译器将报错
类转换函数
将对象转换为其他类型,如将对象转换为基本类型
转换函数定义如下:
operaro type();
- 可使用
explicit
关闭隐式转换,但仍然允许强制转换(C++11
) - 转换函数必现是类方法
- 转换函数不能有参数
- 当隐式转换存在二义性时,需要显式强制转换