参考:黄邦勇帅

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++】重载的更多相关文章

  1. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  2. PHP类和对象之重载

    PHP中的重载指的是动态的创建属性与方法,是通过魔术方法来实现的.属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值.读取.判断属性是否设置.销毁属性. ...

  3. C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱

    一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...

  4. new/delete重载

    在c++中,有时我们需要在运行阶段为一个变量分配未命名的内存,并使用指针来访问它,这里就可以用到new关键字.另外需要指出的是,new分配的内存块通常与常规变量分配的内存块不同,常规变量的值都储存在被 ...

  5. java重载与覆写

    很多同学对于overload和override傻傻分不清楚,建议不要死记硬背概念性的知识,要理解着去记忆. 先给出我的定义: overload(重载):在同一类或者有着继承关系的类中,一组名称相同,参 ...

  6. 【C++】多态性(函数重载与虚函数)

    多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...

  7. C++ 运算符重载时,将运算符两边对象交换问题.

    在C++进行运算符重载时, 一般来讲,运算符两边的对象的顺序是不能交换的. 比如下面的例子: #include <iostream> using namespace std; class ...

  8. C++重载new和delete运算符

    内存管理运算符 new.new[].delete 和 delete[] 也可以进行重载,其重载形式既可以是类的成员函数,也可以是全局函数.一般情况下,内建的内存管理运算符就够用了,只有在需要自己管理内 ...

  9. Java学习笔记之方法重载

    被重载的方法必须具有不同的参数列表.不能基于不同修饰符或返回值类型来重载方法. package welcome; public class TestMethodOverloading { public ...

  10. Qt 5.0+ 中 connect 新语法与重载函数不兼容问题的解决方法,以及个人看法

    Qt 5.0+ 版本提供了 connect 的新语法,相比之前的语法新语法可以提供编译期检查,使用也更方便.可是使用过程中发现一个小问题——当某个 signal 和成员函数是重载关系的时候,qmake ...

随机推荐

  1. SpringBoot 中使用shiro注解使之生效

    在shiroConfig配置类中增加如下代码: /** * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro ...

  2. 【转】给大家分享一下目前mlc颗粒的内存卡资料

    以下信息是LZ从其它论坛上找到的TF卡也是有讲究的,一分价钱一分货 dboy99 楼主 骚(6) #1楼 2015-8-5 14:49引用Micro SD卡也叫TF卡,作为手机扩展存储空间的唯一方式用 ...

  3. JQuery实现的智能表单提示

    实现一个类似如此效果的表单验证:

  4. [剑指Offer] 26.二叉搜索树与双向链表

    [思路]因为二叉搜索树的中序遍历就是递增排列的,所以只要在中序遍历时将每个结点放入vector中,再分别为每个结点的左右指针赋值即可. /* struct TreeNode { int val; st ...

  5. [剑指Offer] 12.数值的整数次方

    [思路1]递归 class Solution { public: double Power(double base, int exponent) { ){ /base; exponent = -exp ...

  6. kudu介绍及安装配置

    kudu介绍及安装配置 介绍 Kudu 是一个针对 Apache Hadoop 平台而开发的列式存储管理器.Kudu 共享 Hadoop 生态系统应用的常见技术特性: 它在 commodity har ...

  7. line-height用法总结

    Line-height是前端用语,经常被前端开发人员经常使用. line-height设置1.5和150%有什么区别?这是一个比较常见的前端面试题. 定义: line-height指的是文本行基线间的 ...

  8. BZOJ4373 算术天才⑨与等差数列(线段树)

    看上去很难维护,考虑找一些必要条件.首先显然最大值-最小值=k*(r-l).然后区间内的数需要模k同余.最后区间内的数两两不同(k=0除外).冷静一下可以发现这些条件组合起来就是充分的了. 考虑怎么维 ...

  9. JSONP以及Spring对象MappingJacksonValue的使用方式

    什么是JSONP?,以及Spring对象MappingJacksonValue的使用方式 原文: https://blog.csdn.net/weixin_38111957/article/detai ...

  10. mapreduce出现大量task被KILLED_UNCLEAN的3个原因

    Request received to kill task 'attempt_201411191723_2827635_r_000009_0' by user ------- Task has bee ...