C++基础知识之运算符重载详解

目录
  • 运算符重载
  • 方式一,使用成员函数重载运算符需求:把牛肉换猪肉,羊肉换猪肉
  • 方式二,使用非成员函数【友元函数】重载运算符
  • 两种方式的区别
  • 两种方式的选择:
  • 总结

运算符重载

  • 为什么要使用运算符重载

-C/C++的运算符,支持的数据类型,仅限于基本数据类型。

  • 问题:一头牛+一头马 = ?(牛马神兽?)

一个圆 +一个圆 = ? (想要变成一个更大的圆)
一头牛 – 一只羊 = ? (想要变成4只羊,原始的以物易物:1头牛价值5只羊)

  • 解决方案:

使用运算符重载

方式一, 使用成员函数重载运算符 需求:把牛肉换猪肉, 羊肉换猪肉

规则:

一斤牛肉:2斤猪肉

一斤羊肉:3斤猪肉

实现:

牛 + 牛 = ?猪肉

牛 + 羊 = ?猪肉

Cow类

> Cow.h
#pragma once
class Pork;
class Sheep;
class Cow{	//牛类
public:
	Cow(int weight = 0);
	//使用运算符重载, 实现 牛肉 + 牛肉 = 猪肉
	Pork operator+(const Cow& cow);
	//使用运算符重载, 实现 牛肉 + 羊肉 = 猪肉
	Pork operator+(const Sheep& sheep);
private:
	int weight;	//重量
};
_________________________________________________________________________________________________________________________________
> Cow.cpp
#include "Cow.h"
#include "Pork.h"
#include "Sheep.h"
Cow::Cow(int weight){
	this->weight = weight;
}
//一斤牛肉换两斤猪肉
Pork Cow::operator+(const Cow& cow){
	return Pork((this->weight + cow.weight) * 2);
}
//一斤牛肉换两斤猪肉, 一斤羊肉换三斤猪肉
Pork Cow::operator+(const Sheep& sheep){
	int tmp = (this->weight * 2) + (sheep.getWeight() * 3);
	return Pork(tmp);
}

Sheep类

> Sheep.h
#pragma once
//羊类
class Sheep{
public:
	Sheep(int weight = 0);
	int getWeight() const;
private:
	int weight;	//重量
};
_________________________________________________________________________________________________________________________________
> Sheep.cpp
#include "Sheep.h"
Sheep::Sheep(int weight){
	this->weight = weight;
}
int Sheep::getWeight() const{
	return weight;
}

Pork类

> Pork.h
#pragma once
#include <string>
using namespace std;
class Pork{	//猪肉类
public:
	Pork(int weight = 0);
	string description() const;
private:
	int weight;
};
_________________________________________________________________________________________________________________________________
> Pork.cpp
#include <sstream>
#include "Pork.h"
Pork::Pork(int weight){
	this->weight = weight;
}
string Pork::description() const{
	stringstream ret;
	ret << this->weight << "斤";
	return ret.str();
}

main.cpp

#include <iostream>
#include <Windows.h>
#include "Cow.h"
#include "Pork.h"
#include "Sheep.h"
using namespace std;
int main(void) {
	Pork p1;
	Cow c1(100);
	Cow c2(200);
	Sheep s1(100);
	//调用运算符重载 Pork operator+(const Cow& cow);
	p1 = c1 + c2;
	cout << "牛 + 牛 = 猪肉:" << p1.description() << endl;
	//调用运算符重载 Pork operator+(const Sheep& c1);
	p1 = c1 + s1;
	cout << "牛 + 羊 = 猪肉:" << p1.description() << endl;
	//羊+牛会报错, 因为没有定义对应的羊+牛运算符重载
	//p1 = s1 + c1;
	system("pause");
	return 0;
}

方式二, 使用非成员函数【友元函数】重载运算符

实现:

牛 + 牛 = ?猪肉

牛 + 羊 = ?猪肉

Cow类

> Cow.h
#pragma once
class Pork;
class Sheep;
class Cow{	//牛类
public:
	Cow(int weight = 0);
	//使用友元运算符重载, 实现 牛肉 + 牛肉 = 猪肉
	friend Pork operator+(const Cow& c1, const Cow& c2);
	//使用友元运算符重载, 实现 牛肉 + 羊肉 = 猪肉
	friend Pork operator+(const Cow& c1, const Sheep& s1);
private:
	int weight;	//重量
};
_________________________________________________________________________________________________________________________________
> Cow.cpp
#include "Cow.h"
Cow::Cow(int weight){
	this->weight = weight;
}

Sheep类

> Sheep.h
#pragma once
//羊类
class Sheep{
public:
	Sheep(int weight = 0);
	int getWeight() const;
private:
	int weight;	//重量
};
_________________________________________________________________________________________________________________________________
> Sheep.cpp
#include "Sheep.h"
Sheep::Sheep(int weight){
	this->weight = weight;
}
int Sheep::getWeight() const{
	return weight;
}

Pork类

> Pork.h
#pragma once
#include <string>
using namespace std;
class Pork{	//猪肉类
public:
	Pork(int weight = 0);
	string description() const;
private:
	int weight;
};
_________________________________________________________________________________________________________________________________
> Pork.cpp
#include <sstream>
#include "Pork.h"
Pork::Pork(int weight){
	this->weight = weight;
}
string Pork::description() const{
	stringstream ret;
	ret << this->weight << "斤";
	return ret.str();
}

main.cpp

#include <iostream>
#include <Windows.h>
#include "Cow.h"
#include "Pork.h"
#include "Sheep.h"
using namespace std;
//要想访问类的私有数据成员, 就把这个函数定义为友元
Pork operator+(const Cow& c1, const Cow& c2) {
	return ((c1.weight + c2.weight) * 2);
}
//要想访问类的私有数据成员, 就把这个函数定义为友元
Pork operator+(const Cow& c1, const Sheep& s1) {
	return((c1.weight * 2) + (s1.getWeight() * 3));
}
int main(void) {
	Pork p1;
	Cow c1(100);	//100斤的牛
	Cow c2(200);	//200斤的牛
	Sheep s1(100);	//100斤的羊
	//调用 friend Pork operator+(const Cow& c1, const Cow& c2);
	p1 = c1 + c2;
	cout << "使用友元 牛 + 牛 = 猪肉:" << p1.description() << endl;
	//调用 friend Pork operator+(const Cow& c1, const Sheep& s1);
	p1 = c1 + s1;
	cout << "使用友元 牛 + 羊 = 猪肉:" << p1.description() << endl;
	system("pause");
	return 0;
}

两种方式的区别

区别:

使用成员函数来实现运算符重载时,少写一个参数,因为第一个参数就是this指针。

两种方式的选择:

  • 一般情况下,单目运算符重载,使用成员函数进行重载更方便(不用写参数)
  • 一般情况下,双目运算符重载,使用友元函数更直观

方便实现a+b和b+a相同的效果,成员函数方式无法实现。

例如: 100 + cow; 只能通过友元函数来实现

cow +100; 友元函数和成员函数都可以实现

  • 特殊情况:

(1)= () [ ] -> 不能重载为类的友元函数!!!(否则可能和C++的其他规则矛盾),只能使用成员函数形式进行重载。

(2)如果运算符的第一个操作数要求使用隐式类型转换,则必须为友元函数(成员函数方式的第一个参数是this指针)

注意:

同一个运算符重载, 不能同时使用两种方式来重载,会导致编译器不知道选择哪一个(二义性)

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • c++运算符重载基础知识详解

    实际上,很多C++运算符已经被重载.eg:将*运算符用于地址,将得到存储在这个地址中的值,将他用于2个数字时,得到的将是他们的乘积.C++根据操作数的数目和类型来决定采用哪种操作. C++允许将运算符重载扩展到用户定义的类型.例如,允许使用+将两个对象相加.编译器将根据操作数的数目和类型决定使用加法定义.运算符重载可以使代码看起来更自然.例如,将2个数组相加是一种常见的运算.通常,需要使用下面这样的for循环来实现: 复制代码 代码如下: for (int i = 0; i < 20; i++)

  • C++运算符重载限制介绍

    目录 一.重载限制 1.必须至少有一个操作数是用户定义的类型 2.不能违反运算符原来的规则 3.不能创建新运算符 4.禁止名单 5.部分运算符只能通过成员函数重载  文章转自公众号:Coder梁(ID:Coder_LT) 一.重载限制 上一篇我们讲了在类和结构体当中重载运算符,关于运算符的重载并不是随心所欲的.C++给出了一些限制,从而保证了规范,以及程序运行的准确性. 下面我们就来一一来看下: 1.必须至少有一个操作数是用户定义的类型 这句话看不明白没有关系,我们只需要记住它的目的就好了.它的

  • 聊聊C++ 运算符重载知识

    前言 1.运算符重载是一种形式的C++多态. 2.重载运算符可以使代码看起来更加自然. 回顾类 在正常构造类的时候,有些成员方法可以不用写出来,例如在这样一个表示时间的类中,拷贝构造函数只是浅拷贝,和系统默认的步骤是一样的,可以不用写了. 同样,析构函数如果在对象死亡之前没有必须要做的事情,也可以不用写. 所以在下面的例子中,拷贝构造和析构函数可以省略. class Time { public: Time(); Time(const Time& src) { _hour = src._hour;

  • C++运算符重载详情介绍

    文章转自公众号:Coder梁(ID:Coder_LT) C++当中除了函数可以重载之外,其实运算符也是可以重载的.我们之前已经接触过一些,可能大家没有意识到. 举个例子,乘号*,运用在指针上,就是取值的意思,而运用在算数当中,则是乘法的意思.同样一个符号,用在不同的地方,起到了不同的效果.这其实就是一种重载,C++根据操作数的数目和类型来决定要使用哪一种操作. 另外C++允许将运算符重载扩展到用户自定义的类型,也就是结构体和类当中.比如,我们可以将重载加号,对两个对象相加. 其实这种用法也出现过

  • C++中的运算符重载详解

    目录 1.引例 2.类中自动建立的函数 3.重载赋值运算符解析 总结 1.引例 class Complex { private: double Real,Image; public: Complex():Real(0),Image(0) {} Complex(double r, double i) : Real(r),Image(i) {} ~Complex() {} }; int main() { Complex c1(1.2,2.3); Complex c2(45,56); Complex

  • C++基础知识之运算符重载详解

    目录 运算符重载 方式一,使用成员函数重载运算符需求:把牛肉换猪肉,羊肉换猪肉 方式二,使用非成员函数[友元函数]重载运算符 两种方式的区别 两种方式的选择: 总结 运算符重载 为什么要使用运算符重载 -C/C++的运算符,支持的数据类型,仅限于基本数据类型. 问题:一头牛+一头马 = ?(牛马神兽?) 一个圆 +一个圆 = ? (想要变成一个更大的圆)一头牛 – 一只羊 = ? (想要变成4只羊,原始的以物易物:1头牛价值5只羊) 解决方案: 使用运算符重载 方式一, 使用成员函数重载运算符

  • Vue 2.0入门基础知识之内部指令详解

    1.Vue.js介绍 当前前端三大主流框架:Angular.React.Vue.React前段时间由于许可证风波,使得Vue的热度蹭蹭地上升.另外,Vue友好的API文档更是一大特色.Vue.js是一个非常轻量级的工具,与其说是一个MVVM框架,不如说是一个js库.Vue.js具有响应式编程和组件化的特点.响应式编程,即保持状态和视图的同步,状态也可以说是数据吧:而其组件化的理念与React则一样,即"一切都是组件,组件化思想方便于模块化的开发,是前端领域的一大趋势. 2.内部指令 2-1.v-

  • Java集合基础知识 List/Set/Map详解

    一.List Set 区别 List 有序,可重复: Set 无序,不重复: 二.List Set 实现类间区别及原理 Arraylist 底层实现使用Object[],数组查询效率高 扩容机制 1.6采用(capacity * 3)/ 2 + 1,默认容量为10: 1.7采用(capacity >> 2 + capacity)实现,位移动效率高于数学运算,右移一位等于乘以2倍: 读取速度快,写入会涉及到扩容,所以相对较慢. LinkedList底层采用双向链表,只记录 first 和 las

  • Python基础知识之变量的详解

    一.定义 在python中,变量名只有在第一次出现的时候,才是定义变量.当再次出现时,不是定义变量,而是直接调用之前定义的变量. 二.命名方法 2.1小驼峰命名法 第一个单词以小写字母开始,后续单词的首字母大写 firstName , lastName 2.2大驼峰命名法 每一个单词的首字母都采用大写字母 FirstName , LastName 2.3下划线命名法 每个单词之间用下划线连接起来 first_name , last_name 三.命名规则 3.1标识符 开发人员自定义的一些符号和

  • Python的运算符重载详解

    一.前言 运算符重载:为运算符定义方法 所谓重载,就是赋予新的含义同一个运算符可以有不同的功能 二.重载作用 让自定义的实例像内建对象一样进行运算符操作让程序简介易读对自定义对象将运算符赋予新的规则 运算符和特殊方法 运算符重载 # @function:运算符重载 # @Description: 一只萤火虫 class MyInteger: """ 创建一个自定义的整数类型 """ def __init__(self, data=0): # 1.

  • C++中运算符重载详解及其作用介绍

    目录 概述 函数重载 运算符重载 C++ 的运算符 重载运算符的规则 成员函数实现 Complex 加法 运算符重载的方法 多种实现方法 实现 operator+= 三种运算符重载函数 成员函数实现 友元函数实现 输出结果 重载单元运算符 例子 重载二元运算符 例子 重载 I/O 插入运算符 << 提取运算符 >> 总结 概述 运算符重载 (Operator Overloading) 函数重载 重载: 将同一名字重新赋予新的含义. 函数重载: 对一个函数赋予新的含义, 使之实现新功

  • Python入门教程之运算符重载详解

    目录 如何重载Python中的运算符 在 Python中重载比较运算符 重载相等和小于运算符 用于运算符重载的 Python 魔术方法或特殊函数 二元运算符 比较运算符 赋值运算符 一元运算符 运算符重载意味着赋予超出其预定义的操作含义的扩展含义.例如运算符 + 用于添加两个整数以及连接两个字符串和合并两个列表.这是可以实现的,因为 '+' 运算符被 int 类和 str 类重载.您可能已经注意到,相同的内置运算符或函数对不同类的对象显示不同的行为,这称为运算符重载. # Python 程序显示

  • Python编程基础之运算符重载详解

    目录 学习目标 一.运算符重载 (一)概述 (二)加法运算重载符 1.概述 2.案例演示 总结 学习目标 1.掌握运算符重载 2.会定制对象字符串的形式 一.运算符重载 (一)概述 运算符重载是通过实现特定的方法使类的实例对象支持Python的各种内置操作 .例如:+运算符是类里提供的__add__这个函数,当调用+实现加法运算的时候,实际上是调用了__add__方法. 方法 说明 何时调用方法 __add__ 加法运算 对象加法:x+y,x+=y __sub__ 减法运算 对象减法:x-y,x

  • C++中的四个默认成员函数与运算符重载详解

    本文主要给大家介绍了关于C++默认成员函数与运算符重载的相关内容,分享出来公的敬爱啊参考学习,话不多说,来一起看看详细的介绍: 一:类和对象的基础知识:类的定义,访问限定符,面向对象封装性,对象的大小计算等等.(编译环境为VS2015) 面向对象程序设计: 概念:(Object Oriented Programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法.对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性.灵活性和扩展性. 类:类的基

随机推荐