【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 ...
随机推荐
- io学习2-磁盘阵列RAID
磁盘阵列 RAID(Redundant ArrayOf Inexpensive Disks) 如果你是一位数据库管理员或者经常接触服务器,那对RAID应该很熟悉了,作为最廉价的存储解决方案,RAID早 ...
- Spring框架(依赖注入)
特点 1轻量级和侵入性低 2依赖注入和面向接口实现松耦合 3面向切面编程 减少样式代码 专有名词: 1依赖注入:对象无需自行管理依赖关系.通过系统负责协调在创建对象的第三方组件的设定,实现依赖关系自动 ...
- 201621044079 week05-继承、多态、抽象类与接口
作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口 interface关键字 implements has-a;comparable co ...
- 一道ioccc题目
国际C语言混乱大赛的一个题: main() {printf(&unix["\021%six\012\0"],(unix)["have"]+"f ...
- capacilitys 持续集成
目前看好像是说以docker为例来看看这个权限到底是怎么来的? 可以通过在二进制上setcap得到,也可以通过函数自己用setcap得到,两种方法,docker肯定是第二种方法啊,docker中间肯定 ...
- js阻止冒泡事件和默认事件的方法
阻止默认事件 function stopDeFault(e){ if(e&&e.preventDefault){//非IE e.preventDefault(); }else{//IE ...
- Java IO 流 体系结构图
- [NOIP2017]列队 线段树
---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当 ...
- Android:Google出品的序列化神器Protocol Buffer使用攻略
习惯用 Json.XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式 ...
- vue 时间戳转 YYYY-MM-DD h:m:s
export default function(data = 1){ let myDate; if(data !== 1){ myDate = new Date(data * 1000); }else ...