标准C++(3)重载
一、函数的重载
c++中同一作用域下能够定义同名的函数(这就叫重载),但必须满足如下要求:
1、函数的参数列表必须不同,可以使参数数量不同,也可以使参数的类型不同,甚至是参数的顺序不同。
2、函数的返回值可以不同,但必须满足条件一。
3、同一作用域下的函数才会形成重载
4、常函数与非常函数也能构成重载
重载决策
当编译器遇到对重载函数的调用,它会优先选择与调用类型匹配的函数声明进行调用,这个过程叫重载决策
若没有找到完全匹配的函数声明,编译器会找到参数数量匹配但类型差异不大的函数进行调用并做隐式的类型转换。
【例】
int func(int num)
{
}
int func(int num1,int num2)
{
} int main()
{
char ch = ;
func(ch);
}
上面的例子中,最后会将变量ch做类型转换成int 然后调用 int func(int num)
如果没找到类型匹配的函数,此时又有多个函数在变量强制类型转换后能够调用,此时就会产生编译错误
【例】
void func(char *p)
{
} void func(long* num)
{
} int main()
{
func();
}
二、运算符重载
C++在类中能够对大部分运算符进行重载,即将运算符的功能重新实现。
对运算符重载有以下规则:
1、对运算符的重载不改变运算符原先运算优先级,而且运算符能够操作的数也是不变的。如,一个自变运算符的重载后也只能对一个变量进行操作,不能使它变成对两个变量操作。
2、重载运算符必须有一个类类型的参数。也就是说不能 int operator+(int,int);
3、&& 和 || 重载后不再具有短路特性
4、只能对已有的运算符进行重载,不能自己定义新的运算符
5、运算符进行重载应根据新类型的实际需要,在不大幅改变运算符本身的逻辑的情况下,对运算符的功能进行加强。也就是说,重载后的运算符功能应与原来的类似。
6、不能重载的运算符有五个:成员运算符 < . > 成员指针访问运算符 < .* > 域运算符 < :: > 字节长度运算符 < sizeof > 条件运算符 < ?: >
运算符重载的语法
返回值 operator 运算符 (参数) //参数中必须有一个类类型
【例】
#include <iostream> using namespace std; class person
{
public:
int num1;
int num2;
person(int x,int y)
{
num1 = x;
num2 = y;
}
//friend person operator -- (person& a);
friend person operator -- (person& a,int);
person& operator - (person& that)
{
this->num1 = that.num1-that.num2;
this->num2 = that.num2-that.num1;
return *this;
}
person operator -- (void)
{
this->num1--;
this->num2--;
return *this;
}
void show(void)
{
cout << num1 << " " << num2 << endl;
}
}; person operator -- (person& a,int)
{
person b = a;
a.num1--;
a.num2--;
return b;
} int main()
{
person per(,);
(--per).show();
(per--).show();
per.show();
}
在类外对运算符进行重载也是允许的,但参数里必须有一个类类型的变量
三、赋值构造
赋值构造实际上就是对运算符 = 的重载,在设计类时如果没有写赋值构造编译器会自动生成一个。
出现已初始化的两个对象之间的赋值时,便会调用赋值构造。
编译器自动生成的赋值构造只是对参数的简单赋值,如果遇到指针成员时无法拷贝指针指向的内容,而只是将指针的值赋值给左边的对象的成员。
因此我们需要自定义运算符=的重载函数,先判断自赋值,然后为指针成员释放申请内存,拷贝内容
【例】
#include <iostream>
#include <string.h>
using namespace std; class person
{
public:
int num1;
int num2;
char *name;
person(int x,int y,const char* ch)
{
num1 = x;
num2 = y;
name = new char[strlen(ch)+];
strcpy(name,ch);
}
person& operator = (person& that)
{
if(&that != this) //检查自赋值
{
delete[] this->name; //释放原先name的内存
this->name = new char[strlen(that.name)+]; //重新为name申请内存
strcpy(this->name,that.name);
num1 = that.num1;
num2 = that.num2;
}
return *this;
}
void show(void)
{
cout << num1 << " " << num2 << " " << name << endl;
}
}; int main()
{
person per1(,,"jack");
person per2(,,"tom");
per1.show();
per2.show();
per1 = per2;
per1.show();
per2.show();
}
关于自赋值
在写代码过程中可能会出现间接的自赋值情况,当delete其中一个对象的时候,再使用另一个就可能会造成错误
标准C++(3)重载的更多相关文章
- Java中重载和重写的区别
重载 overloading 1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载是一个类中多态性的一种表现. 2) Java的方法重载,就 ...
- Java 读书笔记 (十七) Java 重写(Override)与重载(Overload)
重写(Override) 重写是子类对父类的允许访问的方法的实现过程重新编写,返回值和形参都不能改变,即外壳不变,核心重写. // 如果重写不是相当于重新定义了一个方法?那为什么不直接写,还要exte ...
- java中方法的重载和覆盖
java中方法的重载和覆盖 先来了解一下这两个名词的含义. 重载: 在一个类当中才可以重载,方法名相同,参数个数不同或参数个数相同而参数类型不同. 覆盖: 又称重写,在派生类(子类)中重写基类(父类) ...
- C++基础 学习笔记五:重载之运算符重载
C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...
- 为什么Java不支持运算符重载?
另一个类似棘手的Java问题.为什么 C++ 支持运算符重载而 Java 不支持? 有人可能会说+运算符在 Java 中已被重载用于字符串连接,不要被这些论据所欺骗.与 C++ 不同,Java 不支持 ...
- C++初阶(运算符重载汇总+实例)
运算重载符 概念: 运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似. 函数原型: 返回值 operator操作符(参数列表) 注意: ...
- string和vector
一.String对象 1.string s; s.size(); //返回的是s中字符的个数,也是s的长度: //string对象最后没有加空字符 //size()返回的是string::s ...
- java基础笔记
1. 成员变量会自动的进行初始化,但是局部变量不会: 2. equals传引用值,==传地址值:当一个对象是引用类型时,就必须使用equals进行比较. 3. 继承:实现代码的复用,继承关系以一种验证 ...
- C和C++格式转换
一.引用参数和指针的转换 标准C不支持引用参数,对此需进行转换.下面以bo1-1.cpp和bo1-1.c中DestroyTriplet()函数为例来说明这种转换. bo1-1.cpp中含有引用参数的函 ...
- 挑战10个最难的Java面试题(附答案)【上】【华为云技术分享】
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/devcloud/article/deta ...
随机推荐
- VlAN-9-存储VLAN配置
vlan和vtp配置可能存储在vlan.dat和运行配置中 对于vtp v3来说无论哪种模式正常和拓展范围的vlan都被存储在vlan.dat文件中,如果为透明或off,vlan配置也会出现在运行配置 ...
- Beanshell vs JSR223 vs Java JMeter脚本:性能关闭你一直在等待!
有几个选项可用于执行自定义JMeter脚本并扩展基线JMeter功能.查看最流行的扩展机制,比较性能并分析哪一个是最好的. 这是乐队之战,JMeter风格. Beanshell V. JSR223 V ...
- python进阶10 MySQL补充 编码、别名、视图、数据库修改
python进阶10 MySQL补充 编码.别名.视图.数据库修改 一.编码问题 #MySQL级别编码 #修改位置: /etc/mysql/mysql.conf.d/mysqld.cnf def ...
- 牛客网练习赛34-D-little w and Exchange(思维题)
链接:https://ac.nowcoder.com/acm/contest/297/D 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...
- PHP全国省市区地址分割提取脚本程序
github地址: https://github.com/zmxfree/addressapart 比如将 浙江省杭州市江干区XX路X号 分割成 浙江省 杭州市 江干区 XX路X号,方便excel操作 ...
- 规则引擎.Net Core
.Net Core 环境下构建强大且易用的规则引擎 https://www.cnblogs.com/chenug/p/9160397.html 本文源码: https://github.com/jon ...
- setTimeout的异步传输机制
setTimeout是异步的,在设置完setTimeout后,指定代码会在设定的时间后加入到任务队列,但并不是立即执行,js是单线程语言,所有的代码按顺序执行,即同步执行,同步执行的代码放在执行队列中 ...
- TestNG ABC
TestNG ABC 资源 官网 :http://testng.org/doc/index.html Maven示例 <dependency> <groupI ...
- 洛谷P1965 转圈游戏
https://www.luogu.org/problem/show?pid=1965 快速幂 #include<iostream> #include<cstdio> #inc ...
- JAVA基础之字节流与字符流
个人理解: IO流就是将数据进行操作的方式,因为编码的不同,所以对文件的操作就产生两种.最好用字节流,为了方便看汉字等,(已经确定文字的话)可以使用字符流.每个流派也就分为输入和输出,这样就可以产生复 ...