【C++】重载
参考:黄邦勇帅
1.操作符重载函数作为类的成员和友元或者独立于类的区别:
当操作符重载函数作为类的成员函数时,操作符重载函数的参数会比作为友元或者独立于类的操作符重载函数少一个参数,因为操作符重载类成员函数把调用该函数的第一个类的对象作为函数的第一个参数,也就是隐含的 this 指针指向调用该函数的第一个对象,所以会少一个参数。
2.调用操作符重载函数的方式:
调用类中的操作符重载函数的方法:比如在类 hyong 中重定义的+操作符 hyong operator +(hyong m){},有类 hyong 的对象 m和 n 则调用操作符重载函数的方法有 m+n 和 m.operator +(n),前一条语句会自动转换为后面这条语句
调用友元或独立的操作符重载函数的方法:当调用类的友元操作符重载函数或独立的操作符函数时语句 m+n会转换为显示的调用方式,比如有友元或独立操作符重载函数 hyong operator +(hyong a, hyong b){}则当出现m+n 时会转换成语句 operator +(m, n)表达式的第一个对象传给第一个参数,第二个对象传给第二个参数。
3.什么情况下需要把操作符函数作为类的友元或者类的成员
有一种情况必须要求操作符函数作为类的友元函数或者是独立的函数,就是一个内置类型和对象相加的情况。比如有语句 m+1 和 1+m第一条可以在类中定义操作符函数的形式为 hyong operator +(int i){},语句 m+1 可以调用这个函数是正确的,但对于 1+m 就不能调用这个函数了,因为类中的操作符重载函数是最左边的对象是调用该函数的对象,但 1+m最左边的是一个内置整型类型 1,所以不会调用这条语句,对于这种语句就只能把操作符重载函数定义为独立的函数或类的友元函数即形如hyong operator +(int i , hyong a){}这样 1+m就会转换成 operator +(1, m)这样就是正确的。
如果这个操作符重载函数需要访问类中的私有成员时,就应把该函数定义为类的友元函数,如果不需要访问类中的私有成员,则可以定义为友元也可以定义为独立函数。
4.必须把操作符函数作为类成员函数的运算符有:(),[],->和任何赋值运算符,重载这些运算符时必须把操作符函数声明为类的成员函数。
5.重载操作符的限制:
并不是所有的操作符都能被重载。除了. ,.* ,:: ,? : ,sizeof,typeid 这几个运算符不能被重载,其他运算符都能被重载
重载不能改变该运算符用于内置类型时的函义
运算符函数的参数至少有一个必须是类的对象或者类的对象的引用。这种规定可以防止程序员运用运算符改变内置类型的函义。
重载不能改变运算符的优先级。
重载不能改变运算符的结合律。
重载不能改变运算符操作数的个数
6.反回类型问题:可以在语句中反回一个临时对象,也可以反回一个对象的引用,或者反回 this 指针,不过反回临时对象会浪费内存开销,所以最好反回类对象的一个引用。
7.参数传递问题:操作符函数可以按值传递也可以按引用传递,这根据操作符而定,比如对于+运算符既可以把对象按值传递给操作符函数也可以按引用传递给操作符函数,而且+操作符不会改变 原操作数的值 ,所以应把传递类型声明为 const,比如 hyong operator +(const hyong &a, const hyong &b){}。但对于要改变其自身值的操作符比如++运算符,就必须传递引用,且不能把该引用声明为 const 类型,因为如果操作数按值传递的话,传递给操作数函数的 将是一个对象的副本,两个副本是独立的,不能改变到原对象的值,所以应按引用传递对象
重载++运算符
默认++是前缀的,后缀形式要定义一个新的形式。
后缀++由于会产生临时变量,所以效率低于前缀++
#include <iostream>
using namespace std; class A
{
public:
int b;
A()
{
b = ;
}
A(int i)
{
b = i;
}
const A & operator++() //前缀++
{
++b;
return *this;
}
}; const A & operator++(A &j, int i) //后缀++ 会产生一个临时变量,效率低 后面的int i只是为了区分前缀++
{
A t(j);
++j.b;
return t;
} int main()
{
A m, n, k;
m = ++k; //调用了前缀++
cout << m.b << k.b << endl;
n = k.operator++(); //显式调用前缀++
cout << n.b << k.b << endl;
n = k++; //调用了后缀++
cout << n.b << k.b << endl;
n = operator++(k, ); //显式调用后缀++
cout << n.b << k.b << endl; return ;
}
重载+运算符
注意内置类型+对象的情况
#include <iostream>
using namespace std; class A
{
public:
int b;
A()
{
b = ;
}
~A()
{
cout << "A 析构函数" << endl;
}
explicit A(int i) //不允许隐式转换
{
b = i;
}
const A & operator+(const A &j) //
{
A t;
t.b = b + j.b;
return t;
}
friend const A &operator+(const A &j, const int i);
}; const A & operator+(const A &j, const int i) //2 实现 对象+内置类型
{
A t;
t.b = j.b + i;
return t;
} const A & operator+(const int i, const A &j) //3 实现 内置类型+对象 因为没有使用类的私有变量,可以不定义为友元
{
A t;
t.b = j.b + i;
return t;
} int main()
{
A m(), n(), k;
k = m + ; //调用2
cout << m.b << k.b << endl;
k = operator+(m, ); //调用2
cout << m.b << k.b << endl;
k = m + n; //调用1
cout << m.b << n.b << k.b << endl;
k = m.operator+(n); //调用1
cout << m.b << n.b << k.b << endl;
k = + m; //调用3
cout << m.b << k.b << endl;
return ;
}
重载=运算符
1.注意重载赋值运算符和[],(),->运算符必须定义为类的成员函数。
2.重载赋值运算符时应有 处理语句 m=m 的情况。其中 m 是某一个类的对象。如果不处理这样的语句有时会出现问题,具体什么问题有待调查。可以用 this 指针来做处理,比如有语句 const A & operator(A &j)则可以用 if(this==&j) return*this;这样的语句来处理。
3.重载赋值运算符时应反回一个对象。因为赋值运算符的左边是一个对象,所以重载赋值运算符应反回一个类的对象,为了避免不必要的开销,最好是反回一个类的对象的引用。
4.如果程序不 提供显示的赋值运算符则系统会提供一个默认的赋值运算符 。
#include <iostream>
using namespace std; class A
{
public:
int b;
A()
{
b = ;
}
A(int i) //不允许隐式转换
{
b = i;
}
const A & operator=(const A & j)
{
if(this == &j) //需要处理自己等于自己的情况
return *this;
b = j.b;
return *this;
}
}; int main()
{
A m();
A n;
n = m;
n = n;
return ;
}
【C++】重载的更多相关文章
- .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]
方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...
- PHP类和对象之重载
PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的.属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值.读取.判断属性是否设置.销毁属性. ...
- C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱
一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...
- new/delete重载
在c++中,有时我们需要在运行阶段为一个变量分配未命名的内存,并使用指针来访问它,这里就可以用到new关键字.另外需要指出的是,new分配的内存块通常与常规变量分配的内存块不同,常规变量的值都储存在被 ...
- java重载与覆写
很多同学对于overload和override傻傻分不清楚,建议不要死记硬背概念性的知识,要理解着去记忆. 先给出我的定义: overload(重载):在同一类或者有着继承关系的类中,一组名称相同,参 ...
- 【C++】多态性(函数重载与虚函数)
多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...
- C++ 运算符重载时,将运算符两边对象交换问题.
在C++进行运算符重载时, 一般来讲,运算符两边的对象的顺序是不能交换的. 比如下面的例子: #include <iostream> using namespace std; class ...
- C++重载new和delete运算符
内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...
- Java学习笔记之方法重载
被重载的方法必须具有不同的参数列表.不能基于不同修饰符或返回值类型来重载方法. package welcome; public class TestMethodOverloading { public ...
- Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法
Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...
随机推荐
- windows下git hub的GUI软件配置与使用
转载自:http://www.cnblogs.com/haore147/p/3618930.html 1. 安装两个软件 1 2 1. git的命令行程序--git for windows:htt ...
- python之pyquery库
如果熟悉jquery,那么使用pyquery进行网页信息提取将会是非常方便的,因为语法都是一样的 1.字符串初始化 2.url和文件初始化 3.CSS选择器 4.子元素 5.父元素 6.兄弟节点 7. ...
- 利用jquery操作dom时,用event.target优化dom操作
html: <ul id="contents"> <li data-link="#part1">Part 1</li> &l ...
- PHP+AJAX 实现表格实时编辑
https://blog.csdn.net/qq_29627497/article/details/81365107 源码链接:https://pan.baidu.com/s/1fAinVXU-nWt ...
- java基础知识-冒泡排序
//冒泡排序,从数组前面向后循环比较 public static void sort1(int[] aa){ int size=aa.length; int temp; //循环数组 for(int ...
- BZOJ4477 JSOI2015字符串树(可持久化trie)
树上建可持久化trie即可,有点过于裸了.darkbzoj过了然而在bzoj一直wa,不知道哪有锅. #include<iostream> #include<cstdio> # ...
- P3032 [USACO11NOV]二进制数独Binary Sudoku
题目描述 Farmer John's cows like to play an interesting variant of the popular game of "Sudoku" ...
- Java Web开发之路(一)——环境配置
1. 下载JDK(Java Development Kit)工具包.其中包括运行Java程序所必须的JRE环境及开发过程中常用的库文件. (JDK与JRE的关系: JDK是Java的开发环境,在编写J ...
- [NOIP2012] 文化之旅 dfs
这道题就体现了聪明的搜索策略的重要性,如果我们正着搜,判断效率会明显下滑,所以我们就采用倒着搜索.(其实很玄学.....) #include <cstdio> #include <b ...
- HDU1272:小希的迷宫(并查集)
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...