C++运算符重载例程详解

合集下载

C程序设计运算符重载资料

C程序设计运算符重载资料
• 不确定目数运算符是操作数个数不确定,可根据需要 重载为不同的操作数个数,不确定目数运算符只包括 函数调用运算符“()”
• 在中只能重载单目运算符、双目运算符及不确定目数 运算符“()”
4.2.1 运算符重载为类的成员函数
• 通过该类的对象来调用运算符函数,由于对象本身将作为一 个操作数,因此要求第一个操作数的类型为用户自ቤተ መጻሕፍቲ ባይዱ义类, 参数表中的参数个数比操作数个数少一。
• 运算符重载的方法在实质上就是定义一个重载运算符 的函数,在执行被重载的运算符时,系统将调用此函 数实现相应的运算。运算符重载本质就是函数的重载。
• 重载运算符的函数的原型如下:
• 返回值类型运算符(形参表);
• 例如将“+”用于类的加法运算运算符重载的函数原 型可以为:
• ( 1, 2);
例4.2 通过运算符重载实现复数相加的示例。
例4.1 通过函数实现复数相加示例。 声明复数数
{
:
数据成员
;
实部
;
虚部
:
公有函数
( r = 0, i = 0): (r), (i){ } 构造函数
() ;
输出复数
( 1, 2);
复数加法
};
()
输出复数
{
( < 0) << << << "i" << ;
虚部为负
( 0) << << ;
虚部为0
<< << “+” << << “i” << ;
z1();
象的过程中调用输了出构z1造函数,语句将此临时对象作为函

介绍C#中的运算符重载.

介绍C#中的运算符重载.

介绍C#中的运算符重载.介绍 C# 中的运算符重载周融,2007 年 5 ⽉(C) 2001-2007 保留所有权利。

重载是⾯向对象中的⼀个重要概念,它是对象多态性的⼀种不完全体现,⼈们通常所说的重载,往往指的是函数的重载。

本⽂向读者介绍⼀种新的重载模型——运算符重载。

在本⽂中的内容:1、为什么需要运算符重载2、C# 运算符重载决策⽰例3、C# 运算符重载⼀览表4、结论为什么需要运算符重载函数的重载为⼀个对象上的相同⾏为提供不同的参数⽅式,这样,开发⼈员便可以使⽤这些不同的参数实现类似的功能。

⼀组函数重载决策⼀般实现的功能是相同的,例如对 Object 对象上的 ToString() ⽅法就有⼏个重载版本,虽然它们接受的参数不同,但却都表达同⼀个⾏为的最终结果。

参数的不同导致函数重载版本的签名不同,这样编译器很容易知道需要调⽤那⼀个重载版本。

这种技术给开发⼈员带来了⽅便。

现在我们试图对重载的定义进⾏推⼴。

先让我们看看最简单的例⼦,我们通常需要像这样声明并初始化⼀个值类型的变量:int digit = 5;string sayHello = "Hello, World";这⾥的“=”运算符,就是将右边的值传递给左边变量的赋值运算符。

这⾥,5 的类型为 int,“Hello, World”的类型为 string,这与左边被赋值的变量类型完全⼀致。

但对于上述的解释,我们还可以这样认为:5 的类型为 uint 或 byte,"Hello, World"的类型为 char[],那么如此⼀来,赋值运算左边和右边的类型就不在等同,那么编译器如何处理呢?有⼈会说,这就是“隐式类型转换”,这个答案确实很好,但隐式类型转换的规则已经被编译器确定,如果赋值运算的两端不遵循隐式类型转换规则,则需要显式类型转换,例如:char c = '2';string s = (string)c;int i = (int)c;这些显式类型转换并不适⽤于任何场合,也许⼈们希望在其⾃定义的类中也能⽤赋值、加减乘除等语法操作它们。

C++基础系列——运算符重载

C++基础系列——运算符重载

C++基础系列——运算符重载1. 运算符重载简介所谓重载,就是赋予新的含义。

函数重载(Function Overloading)可以让⼀个函数名有多种功能,在不同情况下进⾏不同的操作。

同样运算符重载(Operator Overloading)可以让同⼀个运算符可以有不同的功能。

可以对 int、float、string 等不同类型数据进⾏操作<< 既是位移运算符,⼜可以配合 cout 向控制台输出数据也可以⾃定义运算符重载:class Complex{public:Complex();Complex(double real, double imag);Complex operator+(const Complex &a) const;void display() const;private:double m_real;double m_imag;};// ...// 实现运算符重载Complex Complex::operator+(const Complex &A) const{Complex B;B.m_real = this->m_real + A.m_real;B.m_imag = this -> m_imag + A.m_imag;return B;// return Complex(this->m_real + A.m_real, this->m_imag + A.m_imag);}int main(){Complex c1(4.3, 5.8);Complex c2(2.7, 3.7);Complex c3;c3 = c1 + c2; // 运算符重载c3.display();return 0;}运算结果7 + 9.5i运算符重载其实就是定义⼀个函数,在函数体内实现想要的功能,当⽤到该运算符时,编译器会⾃动调⽤这个函数,它本质上是函数重载。

第12-13讲 运算符重载

第12-13讲 运算符重载
7
7.1.2 运算符重载规则
可以重载C++中除下列运算符外的所有运算符: 类属关系运算符. 成员指针运算符* 作用域分辨符:: sizeof运算符 三目运算符?: 只能重载C++语言中已有的运算符,不可臆造新的。 不能改变操作数个数。 不能改变原运算符的优先级和结合性。 不能改变运算符对预定义类型数据的操作方式。 经重载的运算符,其操作数中至少应该有一个是自定 义类型。
14

void complex:: print()//显示输出复数 { cout<<real; if(imag>0) cout<<"+"; if(imag!=0) cout<<imag<<"i";cout<<endl; } void main() { complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6;//定义6个复数类对象 A1.print(); A2.print(); A3=A1+A2; A3.print(); A4=A1-A2; A4.print(); A5=A1*A2; A5.print(); A6=A1/A2; A6.print(); }
2

class complex { public: double real,imag; //定义一个实部,一个虚部变量 complex(double r=0,double i=0) { real=r; imag=I; } }; main() { complex com1(1.1,2.2),com2(3.3,4.4),total; total=com1+com2; 错误,2个自定义的数据类 return 0; 型complex类型对象相加, } C++无法实现. 希望实现total=com1+com2;重载“+”

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

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

C++基础知识之运算符重载详解⽬录运算符重载⽅式⼀, 使⽤成员函数重载运算符需求:把⽜⾁换猪⾁, ⽺⾁换猪⾁⽅式⼆, 使⽤⾮成员函数【友元函数】重载运算符两种⽅式的区别两种⽅式的选择:总结运算符重载为什么要使⽤运算符重载-C/C++的运算符,⽀持的数据类型,仅限于基本数据类型。

问题:⼀头⽜+⼀头马 = ?(⽜马神兽?)⼀个圆 +⼀个圆 = ?(想要变成⼀个更⼤的圆)⼀头⽜ – ⼀只⽺ = ? (想要变成4只⽺,原始的以物易物:1头⽜价值5只⽺)解决⽅案:使⽤运算符重载⽅式⼀, 使⽤成员函数重载运算符需求:把⽜⾁换猪⾁, ⽺⾁换猪⾁规则:⼀⽄⽜⾁:2⽄猪⾁⼀⽄⽺⾁:3⽄猪⾁实现:⽜ + ⽜ = ?猪⾁⽜ + ⽺ = ?猪⾁Cow类> Cow.h#pragma onceclass 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 onceclass 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指针。

vc 04 运算符重载

vc 04 运算符重载

于是: 于是:
string x,y; x=x+y; //表示串 和串 合并,放入串 表示串x 表示串 和串y 合并,放入串x
这就使对基本类型的预定义运算符" 的含义在串类中被扩展 这就使对基本类型的预定义运算符"+"的含义在串类中被扩展 为对串类对象的合并操作,即运算符"+"被重载. 为对串类对象的合并操作,即运算符" 被重载. 被重载 运算符重载应注意的几个问题: 运算符重载应注意的几个问题: 1,哪些运算符可以重载? 哪些运算符可以重载? 中除了下面四种运算符外, 在C++ 中除了下面四种运算符外,系统预定义的运算符都 能被重载. 能被重载.
string x,y;
那么, 实现两个串的合并. 那么,可以使用函数strcat(x,y)实现两个串的合并. 如果在表示字符串的类对象x, 的特定环境下,运算符" 使 如果在表示字符串的类对象 ,y 的特定环境下,运算符"+"使 用于类对象,能被解释为串对象x 的合并, 用于类对象,能被解释为串对象 和y 的合并,则编程就更方便 了.
例如:下边是运算符重载的另一个例子,程序实现了复数的加 例如:下边是运算符重载的另一个例子, 和减运算. 和减运算.
#include <iostream.h> class Complex { public: Complex() { real=imag=0.0; } Complex(double r) { real=r; imag=0.0; } Complex(double r,double i) { real=r; imag=i; } Complex operator+(const Complex& c); Complex operator-(const Complex& c); friend void print(const Complex& c); private: double real,imag; };

c语言 重载 赋值运算符

c语言 重载 赋值运算符

c语言重载赋值运算符C语言作为一门高级编程语言,提供了丰富的功能以满足各种编程需求。

其中,运算符重载就是一项非常重要的特性。

运算符重载可以让程序员自定义已有运算符在新类型上的操作方式,使得语言更加灵活和强大。

本文将详细介绍C语言中赋值运算符的重载,包括重载的原理、步骤、方法以及注意事项。

1.C语言中的重载概念C语言中的运算符重载是指在已有的运算符上,根据运算对象的类型,赋予新的操作含义。

这种重载是基于类型的,不同类型之间的运算符重载有不同的处理方式。

运算符重载可以让原有运算符在特定类型上具有更符合语义的操作方式,例如对赋值运算符的重载可以让赋值操作更加直观。

2.赋值运算符的重载原理在C语言中,赋值运算符"="原本用于将右侧的值赋给左侧的变量。

当我们对赋值运算符进行重载时,实际上是将原有赋值操作转换为一个新的表达式,这个表达式中包含了重载后的赋值操作。

重载后的赋值运算符需要满足以下条件:- 重载后的赋值运算符仍为一个二元运算符。

- 重载后的赋值运算符的优先级和结合性与其他运算符保持一致。

- 重载后的赋值运算符需要考虑运算对象的类型,以实现正确的赋值操作。

3.重载赋值运算符的步骤与方法重载赋值运算符的步骤如下:- 定义一个函数,该函数的参数列表中包含一个或多个变量引用。

- 在函数体中,对传入的变量进行操作,以实现重载后的赋值操作。

- 使用函数返回值替换原赋值表达式中的右侧值。

以下是一个重载赋值运算符的示例:```c#include <iostream>class MyClass {public:void operator=(const MyClass& other) {// 实现重载后的赋值操作std::cout << "重载赋值运算符被调用" << std::endl;}};int main() {MyClass obj1;MyClass obj2;obj1 = obj2; // 调用重载后的赋值运算符return 0;}```4.重载赋值运算符的注意事项- 重载赋值运算符时,需要确保运算对象具有可赋值性。

C#运算符重载用法实例分析

C#运算符重载用法实例分析
希望本文所述对大家的C#程序设计有所帮助。
这篇文章主要给大家介绍了关于c如何给枚举类型增加一个描述特性的相关资料文中通过示例代码介绍的非常详细对大家的学习或者工作具有一定的参考学习价值需要的朋友们下面来一起学习学习吧
C#运 算 符 重 载 用 法 实 例 分 析
本文实例讲述了C#运算符重载用法。分享给大家供大家参考。具体分析如下:
public class Plane { public virtual double TopSpeed() { return 300.0D;} public static bool operator>(Plane one, Plane two) { return one.TopSpeed() > two.TopSpeed(); } public static bool operator<(Plane one, Plane two) { return one.TopSpeed() < two.TopSpeed(); } } class Jet : Pe TopSpeed() { return 900.0D; } public override string ToString() { return "I'm a Jet"; } } class Airport { [STAThread] static void Main(string[] args) { Plane plane = new Jet(); Console.WriteLine("plane's top speed: {0}",plane.TopSpeed()); Jet jet = new Jet(); Console.WriteLine("jet's top speed: {0}",jet.TopSpeed()); Console.WriteLine("Plane > Jet = {0}", plane > jet); Console.ReadLine(); } }

C_运算符重载_各类详细介绍

C_运算符重载_各类详细介绍
▪ 有关友元函数重载单目运算符后缀方式的表示方法,将在后 面介绍
▪ 说明
运算符重载函数 operator@()可以返回任何类型,甚至可 以是 void类型,但通常返回类型与它所操作的类的类型 相同,这样可使重载运算符用在复杂的表达式中。例如, 在例7-2中,可以将几个复数连续进行加、减、乘、除的 运算。
用友元函数重载单目运算符时,需要一个显式的操作数, 例7-3中,用友元函数重载单目运算符“-”
#include<iostream.h> class nclass{ int a,b; public:
nclass(int x=0,int y=0) { a=x;b=y;} friend nclass operator -(nclass obj); void show(); };
▪ complex operator+(complex com1,complex com2) { return complex(com1.real+com2.real,com1.imag+com2.imag;}
▪ 这种方法是直接将一个无名临时对象创建到主调函数中,那么 运行效率高于前一种。
▪ 单目运算符重载
nclass operator-(nclass obj) { obj.a=-obj.a;
obj.b=-obj.b; return obj;} void nclass::show() { cout<<"a="<<a<<" b"<<b;} ▪ main() ▪{ ▪ nclass ob1(10,20),ob2; ▪ ob1.show(); ▪ ob2=-ob1; ▪ ob2.show(); ▪ return 0; ▪}

C语言运算符的重载详解

C语言运算符的重载详解

C语⾔运算符的重载详解⽬录写⼀个Add函数为什么不⽤加号作为函数名运算符的重载上⾯问题解决总结写⼀个Add函数我们先讨论下⾯代码,并复习前⾯的内容class Complex{private:double Real, Image;public:Complex() :Real(0), Image(0) {}Complex(double r, double i) :Real(r), Image(i) {}~Complex() {}//Complex Add(const Complex* const this,const Complex &c)Complex Add(const Complex& x)const{Complex y;y.Real = Real + x.Real;y.Image = Image + x.Image;return y;//return Complex(this->Real + x.Real, this->Image + x.Image);}void Print(){cout << Real << "+" << Image << "i" << endl;}};int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1.Add(c2);c3.Print();return 0;}直接return可以使⽤⽆名函数直接代替将亡值对象,相⽐可以省⼀次对象的构建我们再分析如果我们使⽤引⽤返回Add函数const Complex& Add(const Complex& x)const{Complex y;y.Real = Real + x.Real;y.Image = Image + x.Image;return y;//return Complex(this->Real + x.Real, this->Image + x.Image);}若我们以引⽤返回,将亡值对象会创建在Add函数的栈帧中,然后返回将亡值地址,函数return结束该空间会被释放、若没有引⽤,构建⽆名对象也就是将亡值对象会构建在主函数的空间中,这⾥使⽤将亡值对象值给到c3是没有问题的我们查看对象的构造与析构class Complex{private:double Real, Image;public:Complex() :Real(0), Image(0) {}Complex(double r, double i) :Real(r), Image(i){cout << "Create:" << this << endl;}Complex(const Complex& x):Real(x.Real),Image(x.Image){cout << "Copy Create:" << this << endl;}~Complex(){cout << "~Complex:" << this << endl;}//Complex Add(const Complex* const this,const Complex &c)Complex Add(const Complex& x)const{return Complex(this->Real + x.Real, this->Image + x.Image);}void Print(){cout << Real << "+" << Image << "i" << endl;}};int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1.Add(c2);c3.Print();return 0;}⾸先我们使⽤引⽤返回需要加上const修饰,这是因为我们返回将亡值在临时空间具有常性,所以普通引⽤是不能进⾏返回的,需要使⽤常引⽤返回const Complex& Add(const Complex& x)const{return Complex(this->Real + x.Real, this->Image + x.Image);}我们发现对临时对象的构建后马上就进⾏析构,那么是怎么将数据拿出给到c3的?这个在最后我们进⾏分析为什么不⽤加号作为函数名//Complex operator+(const Complex* const this,const Complex &c)Complex operator+(const Complex &c) const{return Complex(this->Real + x.Real, this->Image + x.Image);}这⾥是不可以的,加号是⼀个操作符,不能使⽤操作放作为有效的函数名称;但是在C++中为了使这些操作符号能够当作函数名,那么我们需要在前⾯加上⼀个关键字operator//Complex operator+(const Complex* const this,const Complex &c)Complex operator+(const Complex &c) const{return Complex(this->Real + x.Real, this->Image + x.Image);}也就是告诉编译器,加号是⼀个有效的函数名,这就叫做运算符的重载;随后我们之间使⽤ c3 = c1 + c2 就是可以的int main(){Complex c1(12, 23);Complex c2(4.5, 5.6);Complex c3;c3 = c1 + c2;//编译器编译会是下⾯的情况//c3 = c1.operator+(c2);//c3 = operator+(&c1,c2); 加上this指针}运算符的重载⼀个对象,编译器会给它有6个缺省函数我们再来看下⾯这个问题//我们写⼀个赋值运算符重载void operator=(const Object& obj){this->value = obj.value;}//返回类型为void,这样不可以就不可以连等//obja = objb = objc;//obja = objb.operator=(objc);//obja = operator=(&objb,objc); 返回的⽆类型,不能给obja赋值且赋值函数不可以定义为const修饰Object& operator=(const Object& obj){this->value = obj.value;return *this;}obja = objb = objc;//改写obja = objb.operator=(objc);obja = operator=(&objb,objc);obja.operator=(operator=(&objb,objc));operator=(&obja,operator=(&objb,objc));通过返回对象,就可以实现连等;并且我们可以通过引⽤返回,因为此对象的⽣存期并不受函数的影响,不会产⽣⼀个临时对象作为⼀个过度防⽌⾃赋值若是我们将obja给obja赋值,也就是⾃赋值obja = objaoperator=(&obja,obja);我们就需要进⾏⼀步判断Object& operator=(const Object& obj){if(this != &obj)//防⽌⾃赋值{this->value = obj.value;}return *this;}上⾯问题解决我们通过这段代码来看,与上⾯问题相同Object& operator=(const Object& obj){if (this != &obj){this->value = obj.value;}return *this;}};Object& fun(const Object& obj){int val = obj.Value() + 10;Object obja(val);return obja;}int main(){Object objx(0);Object objy(0);objy = fun(objx);cout << objy.Value() << endl;return 0;}我们在这⾥希望通过引⽤返回,这⾥return的临时对象会构建在fun函数的栈帧中,并且在函数结束栈帧释放,随后调⽤赋值运算符重载,但是数值依旧是正确的我们跟踪这个被析构对象的地址,⾸先我们定位在fun函数的return obja;,随后进⼊析构函数将我们的obja进⾏析构接着运⾏到回到主函数进⾏赋值,接着进⼊赋值运算符重载,可以看到,这⾥的obj地址与已被析构的obja地址相同可以看到这个值依旧存在,依旧可以打印给出,这是因为vs2019的特殊性质造成的;我们每次运⾏程序会发现每次的对象地址都在变化,逻辑地址会随机改变,被析构对象的栈帧不会被接下来的赋值运算符重载扰乱地址空间,所以即使我们引⽤返回的对象已经死亡依旧可以将数值正确返回但是在vc中,我们得到的值会是随机值,这是因为vc中每次运⾏程序地址都不会改变,当我们从fun函数退出进⼊赋值语句中,就会将原本存储数据的地址扰乱,继⽽变成了随机值尽管我们引⽤返回能够将数据正确打印,但是该对象已经死亡,这是不安全的,所以我们⼀定不要以引⽤返回对象VS2019具有⼀个特点:当我们调⽤函数,若函数中没有定义局部变量或局部对象时,该函数基本不对栈帧进⾏清扫总结到此这篇关于C语⾔运算符的重载详解的⽂章就介绍到这了,更多相关C语⾔运算符重载内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

C++中运算符重载的规则语法实例

C++中运算符重载的规则语法实例

C++中运算符重载的规则语法实例运算符重载,就是对已有的运算符重新进⾏定义,赋予其另⼀种功能,以适应不同的数据类型。

之前就知道运算符的重载就是将它重新定义,给它新的功能,为的式符合程序员的要求,⼀个例⼦就是,要将坐标相加,但是电脑不知道怎么相加,于是聪明的⼈就赋予了“+”新的定义。

然⽽⼀些严格意义上的⽤法还不是很清楚。

现在就在这总结⼀下。

⾸先运算符重载的规则如下:①、 C++中的运算符除了少数⼏个之外,全部可以重载,⽽且只能重载C++中已有的运算符。

不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作⽤域运算符“::”、“sizeof”、条件运算符“?:”。

②、重载之后运算符的优先级和结合性都不会改变。

③、运算符重载是针对新类型数据的实际需要,对原有运算符进⾏适当的改造。

⼀般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时⾄少要有⼀个操作对象是⾃定义类型。

运算符重载为类的成员函数的⼀般语法形式为:函数类型 operator 运算符(形参表){函数体;}⼲脆将⼀些运算符重新列出下⼀下:可以⽤作重载的运算符:算术运算符:+,-,*,/,%,++,--;位操作运算符:&,|,~,^,<<,>>逻辑运算符:!,&&,||;⽐较运算符:<,>,>=,<=,==,!=;赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*下列运算符不允许重载:.,.*,::,?:(上⾯也说了的)下⾯给例⼦Boxoperator+(const Box&, const Box&);声明加法运算符⽤于把两个 Box 对象相加,返回最终的 Box 对象。

⼤多数的重载运算符可被定义为普通的⾮成员函数或者被定义为类成员函数。

C 运算符重载实例

C  运算符重载实例

1.赋值函数的重载示例程序代码如下#include "stdafx.h"#include <malloc.h>class stack{private:int *sp, top, max;void inflate();public:stack(int size = 10){sp = (int *)malloc(sizeof(int) * size); max = size;top = 0;}int pop();void push(int value);stack & operator=(stack & rightValue); };//栈的容量增倍void stack::inflate(){int index, *tp;tp = (int *)malloc(sizeof(int) * max * 2); for(index = 0; index < top; index++){tp[index] = sp[index];}max += max;free(sp);sp = tp;}//出栈int stack::pop(){if(top <= 0)throw 1;return sp[--top];}//入栈void stack::push(int value){if(top == max)inflate();sp[top++] = value;}//赋值函数stack & stack::operator=(stack & rightValue){top = rightValue.top;max = rightValue.max;sp = (int *)malloc(sizeof(int) * max);for(int index = 0; index < max; index++){sp[index] = rightValue.sp[index];}return *this;}void main(){stack x(100), y, z;z = y = x;}这里要注意的是赋值函数的返回值是stack &,这是为了实现链式表达式,如z = y = x;。

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解三种重载⽅式⾸先,介绍三种重载⽅式:1//作为成员函数重载(常见)2class Person{3 Private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8bool operator<(const Person& b);910 };11bool Person::operator<(const Person& b)12 {13//作为成员函数时,*this即为左操作数a14 ...15 }1//作为友元函数重载2class Person{3private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8 friend bool operator<(const Person& a,const Person& b);910 };11bool operator<(const Person& a,const Person& b)12 {13 ...14 }1//作为普通函数重载(不推荐)2class Person{3public://注意,重载运算符为普通函数时,使⽤到的类成员必须为public4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}89 };10bool operator<(const Person& a,const Person& b)11 {12 ...13 }作为成员函数重载先介绍第⼀种:bool Person::operator<(const Person& b),bool是函数返回类型,Person::只是指定了成员函数所属类名。

C 程序设计(谭浩强完整版)运算符重载

C  程序设计(谭浩强完整版)运算符重载
第十三章
运算符重载
1
函数的重载 所谓函数的重载是指完成不同功能的函数可以具 有相同的函数名。 C++的编译器是根据函数的实参来确定应该调用 哪一个函数的。
int fun(int a, int b) void main(void) { cout<<fun(3,5)<<endl; cout<<fun(5)<<endl; }
由这个函数来完成该运算符应该完成的操作。这 种函数称为运算符重载函数,它通常是类的成员 函数或者是友元函数。运算符的操作数通常也应 该是类的对象。
6
重载为类的成员函数
格式如下:
关键字 <类名> operator<运算符>(<参数表>)
{ 函数体 } 函数名 运算的对象
运算的对象
返回类型
A operator + (A &);
15
class A { int i; public:A(int a=0){ i=a; } void Show(void){ cout<<"i="<<i<<endl; } A operator +(A &a) //重载运算符+ { A t; t.i=i+a.i; return t; } void operator+=(A &a) { i=i+a.i; } 由左操作符调用右操 }; 作符,没有返回值, void main(void) 故函数类型为void。 { A a1(10),a2(20),a3; a1.Show (); a2.Show (); 相当于a3=a1.operator+(a2) a3=a1+a2; a1+=a2; 相当于a1.operator+=(a2) a3.Show (); }

轻松学C#之运算符重载

轻松学C#之运算符重载


”和“>”,判断三个对象的大小, 输出最大对象。 在该例中,返回数据类型必须是bool,否则会提示错误。错 误信息如下: 无法将类型”bool”隐式转换为”重载关系运算符.Program” 而且,如果重载“<”运算符,那么也必须重载“>”运算符, 否则编译器会报错。错误信息如下: 运算符”重载关系运算符.Program.operator >(重载关系运算 符.Program,重载关系运算符.Program)”要求也要定义匹配的 运算符”<”
Team
operator
+
(Team oper1,Team oper2)
//方法代码暂时省略 }



public static是修饰符。Team表示运算的结果类型。operator是 运算符重载的关键字。oper1和oper2是Team类类型的两个参数。 注意:该参数类型必须是对象或者结构。如果不是,会提示 如下错误信息: 运算符的参数必须是包含类型。
返回数据类型 运算符
public static bool { //return true/false; } public static bool { //return true/false; }
operator
>
(Program op1,Program op2)
operator
<
(Program op1,Program op2)
9.1 什么是运算符重载


运算符重载是根据用户所创建的类来定义运算符的含义。 这样运算符的作用完全由用户决定,同时类和类之间的 运算符含义可以不同。换句话说,通过运算符的重载改 变了运算符运算的规则,可以扩展运算符在类中的作用。 通常情况下,运算符只允许数与数、数与数据和数据与 数据之间的运算。通过运算符的重载,不同类型的对象 都可以进行运算。

c语言 重载 赋值运算符

c语言 重载 赋值运算符

c语言重载赋值运算符【原创版】目录1.概述 C 语言中的运算符重载2.赋值运算符重载的规则和注意事项3.示例:实现一个简单的赋值运算符重载正文一、概述 C 语言中的运算符重载C 语言是一种广泛应用的编程语言,其功能丰富,可以实现各种复杂的操作。

在 C 语言中,运算符重载是一种重要的语言特性,它允许程序员根据需要自定义运算符的行为。

运算符重载可以让代码更加简洁,提高程序的可读性。

在 C 语言中,赋值运算符重载是最常用的一种运算符重载方式。

二、赋值运算符重载的规则和注意事项赋值运算符重载是指对 C 语言中的赋值运算符“=”进行重载,以实现特定的功能。

在实现赋值运算符重载时,需要遵循以下规则:1.运算符重载函数必须有一个参数,即要赋值的对象。

2.运算符重载函数不能有返回值。

赋值运算符的功能是将右侧表达式的值赋给左侧的对象,因此不能有返回值。

3.运算符重载函数的函数名以“operator”开头,后跟赋值运算符“=”。

例如,实现一个整数类型的赋值运算符重载,函数名应为“operator=”。

4.在运算符重载函数中,不能修改左侧的对象。

只能通过拷贝构造函数或赋值运算符来修改对象的值。

5.运算符重载函数的参数类型必须与左侧对象的类型匹配。

三、示例:实现一个简单的赋值运算符重载下面是一个简单的示例,实现了一个整数类型的赋值运算符重载。

在这个示例中,我们定义了一个名为“Int”的整数类,并在其中实现了赋值运算符重载。

```c#include <iostream>using namespace std;class Int {public:// 构造函数Int(int value) {this->value = value;}// 拷贝构造函数Int(const Int& other) {this->value = other.value;}// 重载赋值运算符void operator=(const Int& other) {if (this == &other) {return; // 禁止自我赋值}this->value = other.value;}// 打印函数void print() {cout << "Value: " << value << endl;}private:int value;};int main() {Int a, b;a = 10;b = a;b = 20;a.print(); // 输出:Value: 20return 0;}```在这个示例中,我们定义了一个名为“Int”的整数类,并在其中实现了赋值运算符重载。

c程序设计课件第7章运算符重载

c程序设计课件第7章运算符重载
类型的操作数上面。
2
class Money
{public: Money(int y = 0, int j = 0, int f = 0)
构造函数
{ yuan = y; jiao = j; fen = f; optimize( ); }
void Display(string);
private:
Money cost1(10, 3, 5);
if ( jiao >= 10 ){ yuan++; jiao -=10; } }
void Money::Display(string str)
{ cout << str << " = " << yuan << "." << jiao << fen << "¥" <<
endl; } 3
class Money {public: Money(int y = 0, int j = 0, int f = 0) { yuan = y; jiao = j; fen = f; optimize( ); } void Display(string);
调用:total1 = cost1 + cost2; 形参的顺序任意,不要求第一个参数必须为类对象。要
求运算符左侧的操作数与第一个参数对应,运算符右侧
的操作数与第二个参数对应。
13
7.3 重载运算符的规则
❖(1)C++不允许用户自己定义新的运算符,只 能对C++语言中已有的运算符进行重载。例如 ,虽然在某些程序设计语言中用双字符“**” 作为求幂运算符,但是在使用C++进行程序设 计时,不能将“**”作为运算符进行重载,因 为“**”不是C++语言的合法运算符。

C++运算符重载例程详解

C++运算符重载例程详解

运算符重载就是对一个已有的运算符赋予新的含义,使之实现新功能。

下面将通过简单的几个例程阐叙其用法。

例10.1 通过函数来实现复数相加。

#include <iostream>using namespace std;class Complex //定义Complex类{public:Complex( ){real=0;imag=0;} //定义构造函数Complex(double r,double i){real=r;imag=i;} //构造函数重载Complex complex_add(Complex &c2); //声明复数相加函数void display( ); //声明输出函数private:double real; //实部double imag; //虚部};Complex Complex::complex_add(Complex &c2){Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;}void Complex::display( ) //定义输出函数{cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}int main( ){Complex c1(3,4),c2(5,-10),c3; //定义3个复数对象c3=plex_add(c2); //调用复数相加函数cout<<″c1=″; c1.display( ); //输出c1的值cout<<″c2=″; c2.display( ); //输出c2的值cout<<″c1+c2=″; c3.display( ); //输出c3的值return 0;}例10.2 改写例10.1,重载运算符“+”,使之能用于两个复数相加。

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 c3;c3 = c1.Add(c2);}类⾮常简单,下⾯我们要讨论如何写⼀个Add函数,使得两个对象的属性相加,返回⼀个新的对象。

第⼀种:Complex::Complex Add(const Complex &c){Complex co;co.Real = this->Real + c.Real;co.Image = this->Image + c.Image;return co;}问题1:如何写出最节省空间的Add函数?第⼆种:Complex::Complex Add(const Complex &c) const{return Complex(c.Real + this->Real, c.Image + this.Image);}由于不需要改变调⽤对象的属性值,我们给this指针添加const 修饰。

分析过程如下:问题2:为什么第⼀种⽅式不节省空间呢?⾸先第⼀种的代码⽐较繁琐,并且在函数栈帧中⼜创建了⼀个对象(第3⾏)。

并且函数类型是值传递类型(第6⾏),返回的是⼀个将亡值对象。

那么整个Add函数空间会产⽣两个对象,造成空间的浪费。

第⼆中代码创建的是⽆名对象,减少了⼀个co对象的创建,并且将⽆名对象直接作为将亡值对象传递给main函数中的c3。

问题3:我们能否将Add函数改为引⽤类型,这样来减少将亡值对象的创建Complex::Complex &Add(const Complex &c) const{return Complex(c.Real + this->Real, c.Image + this.Image);}VS2019发现报错,不能返回引⽤对象:我们进⾏分析:问题4:我们能否将这个Add函数名改为 + 运算符?//Complex::Complex Add(const Complex &c) constComplex::Complex +(const Complex &c) const{Complex co;co.Real = this->Real + c.Real;co.Image = this->Image + c.Image;return co;}int main(){...//c3 = c1.Add(c2);c3 = c1.+(c2); //将原先Add的地⽅改变为加号。

C++运算符重载的方法详细解析

C++运算符重载的方法详细解析

C++运算符重载的⽅法详细解析运算符重载实质上是函数的重载重载运算符的函数⼀般格式如下:函数类型 operator 运算符名称(形参表列){对运算符的重载处理}例如,想将“+”⽤于Complex(复数)的加法运算,函数的原型可以是这样的:复制代码代码如下:Complex operator + (Complex & c1,Complex &c2);其中,operator是关键字,时候专门⽤于定义重载运算符的函数的,运算符名称就是C++提供给⽤户的预定运算符。

注意:函数名是由operator和运算符组成。

上⾯的operator+就是函数名,意思是“对运算符+重载“。

只要掌握这点,这可以发现,这类函数和其他函数在形式上没有什么区别。

两个形参是Complex类对象的引⽤,要求实参为Complex类对象。

在定义了重载运算符后,可以说:函数operator+重载了运算符+。

在执⾏复数相加的表达式c1+c2时(假设c1+c2都已被定义为Complex),系统就会调⽤operator+函数,把c1+c2作为实参,与形参进⾏虚实结合。

为了说明把运算符重载后,执⾏表达式就是调⽤函数的过程,可以把两个整数相加也想象称为调⽤下⾯的函数:复制代码代码如下:int operator + (int a,int b){return (a+b);}如果有表达式5+8,就调⽤此函数,将5和8作为调⽤函数时的形参,函数的返回值为13,这就是通过函数的⽅法理解运算符。

=====================⽰例代码1.1==================================复制代码代码如下:#include<iostream>using namespace std;class Complex{public:Complex(){real=0;imag=0;}Complex(double r,double i){real=r;imag=i;}Complex operator + (Complex &c2);//声明运算符的"+"函数void display();private:double real;double imag;};Complex Complex::operator+(Complex &c2){Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;}void Complex::display(){cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(){Complex c1(3,4),c2(5,-10),c3;c3=c1+c2;cout<<"c1=";c1.display();cout<<"c2=";c2.display();cout<<"c3=";c3.display();return 0;}分析:在main函数中,“c3=c1+c2;”在将运算符+重载为类的成员函数后,C++编译系统将程序中的表达式c1+c2解释为:c1.operator+(c2);//其中c1+c2是Complex类的对象即以c2为实参调⽤c1的运算符重载函数operator+(Complex & c2),进⾏求值,得到两个复数之和。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

运算符重载就是对一个已有的运算符赋予新的含义,使之实现新功能。

下面将通过简单的几个例程阐叙其用法。

例10.1 通过函数来实现复数相加。

#include <iostream>using namespace std;class Complex //定义Complex类{public:Complex( ){real=0;imag=0;} //定义构造函数Complex(double r,double i){real=r;imag=i;} //构造函数重载Complex complex_add(Complex &c2); //声明复数相加函数void display( ); //声明输出函数private:double real; //实部double imag; //虚部};Complex Complex::complex_add(Complex &c2){Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;}void Complex::display( ) //定义输出函数{cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}int main( ){Complex c1(3,4),c2(5,-10),c3; //定义3个复数对象c3=plex_add(c2); //调用复数相加函数cout<<″c1=″; c1.display( ); //输出c1的值cout<<″c2=″; c2.display( ); //输出c2的值cout<<″c1+c2=″; c3.display( ); //输出c3的值return 0;}例10.2 改写例10.1,重载运算符“+”,使之能用于两个复数相加。

#include <iostream>using namespace std;class Complex{public:Complex( ){real=0;imag=0;}Complex(double r,double i){real=r;imag=i;}Complex operator+(Complex &c2); //声明重载运算符的函数void display( );private:double real;double imag;};Complex Complex::operator+(Complex &c2) //定义重载运算符的函数{ Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;}void Complex∷display( ){ cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}int main( ){ Complex c1(3,4),c2(5,-10),c3;c3=c1+c2; //运算符+用于复数运算cout<<″c1=″;c1.display( );cout<<″c2=″;c2.display( );cout<<″c1+c2=″;c3.display( );return 0;}例10.3 将运算符“+”重载为适用于复数加法,重载函数不作为成员函数,而放在类外,作为Complex类的友元函数。

#include <iostream>using namespace std;class Complex{public:Complex( ){real=0;imag=0;}Complex(double r,double i){real=r;imag=i;}friend Complex operator + (Complex &c1,Complex &c2);//重载函数作为友元函数void display( );private:double real;double imag;};Complex operator + (Complex &c1,Complex &c2)//定义作为友元函数的重载函数{return Complex(c1.real+c2.real, c1.imag+c2.imag);}//简洁的写法void Comple::display( ){cout<<″(″<<real<<″,″<<imag<<″i)″<<endl;}int main( ){Complex c1(3,4),c2(5,-10),c3;c3=c1+c2;cout<<″c1=″; c1.display( );cout<<″c2=″; c2.display( );cout<<″c1+c2 =″; c3.display( );}例10.4 定义一个字符串类String,用来存放不定长的字符串,重载运算符“==”,“<”和“>”,用于两个字符串的等于、小于和大于的比较运算。

为了使读者便于理解程序,同时也使读者了解建立程序的步骤,下面分几步来介绍编程过程。

(1) 先建立一个String类:#include <iostream>using namespace std;class String{public:String( ){p=NULL;} //默认构造函数String(char *str); //构造函数void display( );private:char *p; //字符型指针,用于指向字符串};String∷String(char *str) //定义构造函数{p=str;} //使p指向实参字符串void String∷display( ) //输出p所指向的字符串{cout<<p;}int main( ){String string1(″Hello″),string2(″Book″);string1.display( );cout<<endl;string2.display( );return 0;}(2) 有了这个基础后,再增加其他必要的内容。

现在增加对运算符重载的部分。

为便于编写和调试,先重载一个运算符“>”。

程序如下:#include <iostream>#include <string>using namespace std;class String{public:String( ){p=NULL;}String(char *str);friend bool operator>(String &string1,String &string2);//声明运算符函数为友元函数void display( );private:char *p; //字符型指针,用于指向字符串};String∷String(char *str){p=str;}void String∷display( ) //输出p所指向的字符串{cout<<p;}bool operator>(String &string1,String &string2) //定义运算符重载函数{if(strcmp(string1.p,string2.p)>0)return true;else return false;}int main( ){String string1(″Hello″),string2(″Book″);cout<<(string1>string2)<<endl;}(3) 扩展到对3个运算符重载。

在String类体中声明3个成员函数:friend bool operator> (String &string1, String &string2);friend bool operator< (String &string1, String &string2);friend bool operator==(String &string1, String& string2);在类外分别定义3个运算符重载函数:bool operator>(String &string1,String &string2) //对运算符“>”重载{if(strcmp(string1.p,string2.p)>0)return true;elsereturn false;}bool operator<(String &string1,String &string2) //对运算符“<”重载{if(strcmp(string1.p,string2.p)<0)return true;elsereturn false;}bool operator==(String &string1,String &string2) //对运算符“==”重载{if(strcmp(string1.p,string2.p)==0)return true;elsereturn false;}再修改主函数:int main( ){String string1(″Hello″),string2(″Book″),string3(″Computer″); cout<<(string1>string2)<<endl; //比较结果应该为true cout<<(string1<string3)<<endl; //比较结果应该为falsecout<<(string1==string2)<<endl; //比较结果应该为false return 0;}(4) 再进一步修饰完善,使输出结果更直观。

下面给出最后的程序。

#include <iostream>using namespace std;class String{public:String( ){p=NULL;}String(char *str);friend bool operator>(String &string1,String &string2);friend bool operator<(String &string1,String &string2);friend bool operator==(String &string1,String &string2);void display( );private:char *p;};String∷String(char *str){p=str;}void String∷display( ) //输出p所指向的字符串{cout<<p;}bool operator>(String &string1,String &string2) {if(strcmp(string1.p,string2.p)>0)return true;elsereturn false;}bool operator<(String &string1,String &string2) {if(strcmp(string1.p,string2.p)<0)return true;elsereturn false;}bool operator==(String &string1,String &string2) {if(strcmp(string1.p,string2.p)==0)return true;elsereturn false;}void compare(String &string1,String &string2){if(operator>(string1,string2)==1){string1.display( );cout<<″>″;string2.display( );}elseif(operator<(string1,string2)==1){string1.display( );cout<<″<″;string2.display( );}elseif(operator==(string1,string2)==1){string1.display( );cout<<″=″;string2.display( );}cout<<endl;}int main( ){String string1(″Hello″),string2(″Book″),string3(″Computer″),string4(″Hello″);compare(string1,string2);compare(string2,string3);compare(string1,string4);return 0;}例10.5 有一个Time类,包含数据成员minute(分)和sec(秒),模拟秒表,每次走一秒,满60秒进一分钟,此时秒又从0开始算。

相关文档
最新文档