1 << 重载 以我们先前完成的Date类为例: class Date { public: Date(int year = 1900, int month = 1, int day = 1) {...< _month << "月" << _day << "日" << endl; } 我们运行一下却出现了这样的报错,不匹配操作数 这是因为重载函数里面有两个参数(Date* this, ostream...& out) 作为成员函数重载,this指针占据第一个参数,Date必须是左操作数!...而我们cout 不匹配,如果我们调换位置 发现可以了,但是这样十分不符合逻辑,cout 流向 a1 ???...int _month; int _day; }; ostream& operatorostream& out, Date& d); istream& operator>>(istream
有了对+的重载,编译器就将a+b理解为对运算符函数的调用,即operator+(a,b),因此第 21 行就等价于: c = operator+(a, b); 即以两个操作数 a、b 作为参数调用名为...2 C++重载=(C++重载赋值运算符) 赋值运算符=要求左右两个操作数的类型是匹配的,或至少是兼容的。有时希望=两边的操作数的类型即使不兼容也能够成立,这就需要对=进行重载。...,右边是 const char * 类型,两边类型不匹配;第二条语句出错是因为 strcpy 函数的第一个形参是 char* 类型,而这里实参给出的却是 const char * 类型,同样类型不匹配。...如果没有第 13 行对=的重载,第 34 行的s = "Good Luck,"肯定会因为类型不匹配而编译出错。...运算符可以重载为全局函数。此时函数的参数个数就是运算符的操作数个数,运算符的操作数就成为函数的实参。 运算符也可以重载为成员函数。
~所以我们就可以进行运算符重载,直接以相应的格式输出或者输入内容~ 》 重载>时(流插入和流提取运算符),需要重载为全局函数 》 我们知道>是 二元运算符 , 有两个操作数...(这里一个是cout/cin,一个是类) 》通过查询我们可以发现 cout是ostream类型,cin是istream类型~ 》注意: ostream类型和istream类型是不支持拷贝的...,第⼀个形参位置是左侧运算对象,调用时就变成了 【 对象<<cout】,不符合我们使用习惯以及代码可读性~ 》重载为全局函数把ostream/istream放到第⼀个形参位置,第二个形参位置是类类型对象..._y; } friend ostream& operatorostream& out, const Example& e); friend istream& operator>>(istream...赋值运算符重载是一个运算符重载,规定 必须重载为成员函数 (与其他的运算符有点区别) 》 赋值运算重载的 参数建议写成const 当前类类型引用 , 减少传值传参拷贝次数,同时不希望对象被修改
|| (*this == d)); } 重载流插入、提取 cout、cin 只能输出、输出内置类型,但如果我们对它进行改造一下,就能直接输出我们的自定义类型 注意: cout 类型为 ostream,...cin 类型为 istream 要使得 cout、cin 变为重载后的左操作数,此时的运算符重载就不能写在类内,因为在类中的函数默认 this 为第一个参数,即左操作数 因此这两个函数比较特殊,需要写在外面...>> 时,右操作数不能用 const 修饰 //在 Date.h 内 //新增几个局部展开 using std::ostream; using std::istream; using std::endl...; namespace Yohifo { class Date { //声明为类的友元函数 friend std::ostream& operatorstd::ostream& out...//直接定义在头文件中,成为内联函数 inline ostream& operatorostream& out, const Date& d) { //此时需要检验日期合法性 if
类内声明: class Demo { 返回值类型 operator 运算符(形参表); } 类外定义: 返回类型 Demo(类名)::operator运算符(形参表) { 函数体 } (2...)双目运算符重载为成员函数 当重载运算符为双目运算符时,形参表中只有一个参数作为右操作数。...(3)单目运算符重载为成员函数 此时参数表中没有参数,只有当前对象作为运算符的一个操作数。...(3) 友元函数重载+重载输入输出流(用的稀烂用的多比较重要) 在左右操作数类型不同时上述重载方式都不能正常使用,这时候就需要两个操作数,在类外重载,因类外不能直接调用,所以要把该函数声明为类的友元。...当用类A类型的值为类A的对象赋值,且类A的数据成员中含有指针的情况下,必须显式提供赋值运算符重载函数。
std::ostream& out, const Date& d); // 其他成员变量和函数 }; // 实现 << 运算符 std::ostream& operatorstd:...::ostream& operatorstd::ostream& out) const; // 其他成员变量和函数 }; // 实现成员函数 std::ostream& Date::operator...5.4.2.1 符合操作数对称性的问题 操作数是 std::ostream(例如 std::cout),右操作数是 Date 对象。...5.4.3 友元函数的优势 将 为友元函数可以很好地解决上述问题,原因如下: 5.4.3.1 符合运算符的对称性 通过友元函数重载 操作数是 ostream...例如,友元函数可以直接访问 Date 类的 _year、_month 和 _day 成员: std::ostream& operatorstd::ostream& out, const Date&
写出函数参数 , 参数一般都是 对象的引用 ; cout 操作数是 ostream cout 标准输出流 , 参数中是引用类型 ; cout 操作数是 Student...s 类对象 , 参数中是引用类型 ; operatorostream& out, Student& s) 再后 , 根据业务完善返回值 , 返回值可以是 引用 / 指针 / 元素 ; 此处返回 void...即可 ; 返回 ostream& 引用类型 , 是为了支持链式调用 cout << s1 << endl; ostream& operatorostream& out, Student& s)...<< endl; ostream& operatorostream& out, Student& s) { // 在函数体中将 Student 对象数据输出到 out 输出流中 out 类型 , 是为了支持链式调用 cout << s1 << endl; ostream& operatorostream& out, Student& s) { // 在函数体中将 Student
::cout std::endl; } 每个函数前面都要加上 template 类型参数列表声明 , 使用域作用符 Father:: 访问函数 ;...ostream& 类型的 , 如果定义在了 类内部 , 左操作数就默认为当前类 ; 代码示例 : #include "iostream" using namespace std; class Student...{ // 左移运算符重载 friend ostream& operatorostream& out, Student& s) public: Student(int x = 0, int...ostream& operatorostream& out, Student& s2) { out << "a:" << s.a << " b: " << s.b << endl; return...; template class Student { // 左移运算符重载 friend ostream& operatorostream& out, Student
5.赋值运算符重载 运算符重载(Operator Overloading)是C++的一种特性,它允许你为类定义或重载运算符,以便让这些运算符能够处理自定义数据类型。...然而,这个重载函数通常不能作为类的成员函数,以下是一些原因: 运算符的左操作数必须是非类类型: 流插入运算符操作数通常是标准输出流对象(如std::ostream)。...如果你将操作数将隐式绑定为类的实例,即第一个操作数必须是类的对象。但在我们通常的用法中,左操作数是std::ostream,而不是类的实例。...; 上面的代码会有问题,因为操作数必须是std::ostream,而类成员函数的隐含调用this指针的方式会将Date对象作为左操作数,这与标准使用方式相冲突。...参数: ostream& out: 这是输出流的引用。通常是std::cout或其他ostream类型的流,如文件流ofstream。
写出函数参数 , 参数一般都是 对象的引用 ; cout 操作数是 ostream cout 标准输出流 , 参数中是引用类型 ; cout 操作数是 String s...类对象 , 参数中是引用类型 ; operatorostream& out, String& s) 再后 , 根据业务完善返回值 , 返回值可以是 引用 / 指针 / 元素 ; 此处返回 void...即可 ; 返回 ostream& 引用类型 , 是为了支持链式调用 cout << s1 << endl; ostream& operatorostream& out, String& s)...< endl; ostream& operatorostream& out, String& s) { cout ostream& operator类型 , 是为了支持链式调用 cout << s1 << endl; ostream& operatorostream& out, String& s) { cout << "调用重载
重载运算符必须至少有一个操作数是用户自定义的类型,不能全部是内置类型。 重载运算符不能改变运算符的优先级和结合性。 重载运算符的行为应该尽可能接近原有运算符的行为,以避免混淆。...friend std::ostream& operatorstd::ostream& os, const Complex& c) { os << c.real << " + " <...:1.0 + 2.0i 在上面的代码中,我们定义了一个友元函数operatorstd::ostream对象和一个Complex对象,然后将Complex对象的内容输出到std::ostream...在运算符重载中,友元的使用非常常见,因为它可以让我们在类外部定义运算符重载函数,从而使得运算符的左操作数可以是非类类型。 让我们来看一个例子。...如果我们将operator*定义为成员函数,那么它的左操作数必须是Complex对象,这显然不能满足我们的需求。因此,我们需要将operator*定义为友元函数。
不能改变运算符的操作数个数:例如,不能将一元运算符重载为二元运算符,反之亦然。 重载的运算符不能是新的类型:重载的运算符必须是 C++ 中已定义的运算符。...运算符重载的实现 成员函数形式:当运算符重载为成员函数时,左侧操作数必须是该类的一个对象(或引用),而右侧操作数可以是任意类型(包括内置类型和该类类型)。...友元函数形式:当运算符重载为友元函数时,两个操作数可以是任意类型(包括内置类型和该类类型),这提供了更大的灵活性。...重载为全局函数把ostream/istream放到第⼀个形参位置就可以了,第⼆个形参位置当类类型对象 实际应用 运算符重载在 C++ 中有着广泛的应用,例如: 复数类:可以重载加法、减法、乘法和除法等运算符...::ostream& operatorstd::ostream& os, const Complex& c) { os << c.real << " + " << c.imag
定义 运算符重载的 实质 是 函数的重载 使用意义 赋予操作符更多的意义,同一个运算符,对不同类型的操作数,所发生的行为不同是 程序更加简洁 写法格式:返回值 operator运算符(参数列表){}...重载的要求: 1、内置类型的操作符不能被重载 2、不能为内置类型定义其他的操作符 3、操作符重载不能改变操作符的优先级 4、操作数个数不能改变 重载方式: 1、类的成员方法 2、类的有友元方法 3、...因为第一个操作类是ostream或istream。...; friend ostream &operatorostream &out, Array &array); friend istream &operator>>(istream...&operatorostream &out, Array &array) { cout operator<<" << endl; for (int i = 0; i <
ostream: __ostream_type& basic_ostream::operator<<(int __n); // 下列代码有什么问题,如何修改?...::ostream& operator std::ostream& os) { os << m1 << m2; return os; } }; int main...() { A a(1,2); std::cout << a; return 0; }; 类basic_ostream没有成员函数“operator <<(const...A&)”, 也不存在全局的: operator ostream&, const A&) 而只有左操作数是自己时才会调用成员重载操作符, 都不符合,所以语法错误。...有两种修改方式: 1) 将“std::cout operator std::cout)”, 2) 或定义全局的: std::ostream& operatorstd
友元函数 之前我们在Time类的示例中,我们重载乘法运算符的参数和其他参数不一样,因为有两种不同的类型,即Time和double类型,限制了调用的方式,我们成员函数调用的过程是b..opertaor*...可以但是没必要 很没有必要 我们按照我们之前重载的方法,我们现在要的形式是coutoperatorostream&os);那么我们调用的时候将会p1<<cout这样虽然可以...,但是看起来很不合理,所以我们选择友元函数 void operatorostream&os,const Time&t) { osostream& operatorstd::ostream& os, const Time& t) { os 操作数都需要作为参数传递给函数 如P1 = P2+P3; 成员函数:P2.operator(P3) 非成员函数:operator(p2,p3) 友元类 友元类(Friend C++lass
(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用(是构造函数的重载) 拷贝构造函数典型调用场景(自动调用): 使用已存在对象创建新对象 函数参数类型为类类型对象 函数返回值类型为类类型对象...函数名字为:关键字operator后面接需要重载的运算符符号。...函数原型:返回值类型 operator操作符(参数列表) 注意: 重载双操作数的运算符,第一个参数是左操作数,第二个参数是右操作数 不能通过连接其他符号来创建新的操作符:比如operator...@ 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的...std::ostream是一个抽象类,它不能被直接实例化 std::cout是标准输出流对象,已经在标准库中定义好了,并且支持输出运算符<<的重载,所以传入参数就好了 3.const成员 将const
== 运算符 , 使用时用法为 a == b ; 左操作数 : 其中 左操作数 是 String a , 这里通过 this 指针调用 , 不需要声明在参数中 ; 右操作数 : 右操作数 是 String...b ; 该操作数需要声明在参数中 , 注意需要声明 引用类型 ; 上述两个是对象类型 , 对象一般传入 指针 或 引用 , 这里传入引用类型 ; operator==(String & s) 再后 ,...=(String& s); // 使用 全局函数 实现 左移运算符 << 重载 // 将全局函数 声明为 String 的友元函数 friend ostream& operatorostream...& 引用类型 , 是为了支持链式调用 cout << s1 << endl; ostream& operatorostream& out, String& s) { cout ostream& operatorostream& out, String& s)" << endl; // 在函数体中将 String 对象的 m_p 指针指向的数据输出到
作为非成员函数(普通函数)重载: 虽然技术上可行,但通常不推荐,因为它无法直接访问类的私有或受保护成员,且需要显式传递所有操作数。...::ostream& operatorstd::ostream& os, const MyClass& obj); }; // 重载插入运算符 std::ostream& operator操作数上。 1. 重载为成员函数 T& operator++(); T& operator--(); 这里的T是类的类型。...重载为全局函数 T& operator++(T&); T& operator--(T&); 参数是对操作数对象的引用(T&),以便可以直接修改对象。 返回值同样是操作数对象的引用。...重载为全局函数 T operator++(T&, int); T operator--(T&, int); 第一个参数是对操作数对象的引用,第二个参数是int类型,同样用于区分前置和后置重载。
6.重载流插入和提取运算符 为了方便输入和输出 istream& operator>>(istream& input, String& str); ostream& operatorostream..., String& str); //输入操作符的重载 friend ostream& operatorostream& output, String& str); //输出操作符的重载 private...m_nRealLen; //根据字符串的实际长度返回是否为空 } const String& String::operator+=(const String& str) { if (m_nBuffSize...>>(istream& input, String& str) { std::cin.get(str.m_pBuff, str.size(), '\n'); //不直接使用cin是怕...return input; } ostream& operatorostream& output, String& str) { for (int i = 0; i < str.length
领取专属 10元无门槛券
手把手带您无忧上云