一、函数的重载

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

  1. Java中重载和重写的区别

    重载 overloading 1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型.重载是一个类中多态性的一种表现. 2) Java的方法重载,就 ...

  2. Java 读书笔记 (十七) Java 重写(Override)与重载(Overload)

    重写(Override) 重写是子类对父类的允许访问的方法的实现过程重新编写,返回值和形参都不能改变,即外壳不变,核心重写. // 如果重写不是相当于重新定义了一个方法?那为什么不直接写,还要exte ...

  3. java中方法的重载和覆盖

    java中方法的重载和覆盖 先来了解一下这两个名词的含义. 重载: 在一个类当中才可以重载,方法名相同,参数个数不同或参数个数相同而参数类型不同. 覆盖: 又称重写,在派生类(子类)中重写基类(父类) ...

  4. C++基础 学习笔记五:重载之运算符重载

    C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...

  5. 为什么Java不支持运算符重载?

    另一个类似棘手的Java问题.为什么 C++ 支持运算符重载而 Java 不支持? 有人可能会说+运算符在 Java 中已被重载用于字符串连接,不要被这些论据所欺骗.与 C++ 不同,Java 不支持 ...

  6. C++初阶(运算符重载汇总+实例)

    运算重载符 概念: 运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似. 函数原型: 返回值 operator操作符(参数列表) 注意: ...

  7. string和vector

    一.String对象 1.string s;      s.size(); //返回的是s中字符的个数,也是s的长度: //string对象最后没有加空字符 //size()返回的是string::s ...

  8. java基础笔记

    1. 成员变量会自动的进行初始化,但是局部变量不会: 2. equals传引用值,==传地址值:当一个对象是引用类型时,就必须使用equals进行比较. 3. 继承:实现代码的复用,继承关系以一种验证 ...

  9. C和C++格式转换

    一.引用参数和指针的转换 标准C不支持引用参数,对此需进行转换.下面以bo1-1.cpp和bo1-1.c中DestroyTriplet()函数为例来说明这种转换. bo1-1.cpp中含有引用参数的函 ...

  10. 挑战10个最难的Java面试题(附答案)【上】【华为云技术分享】

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/devcloud/article/deta ...

随机推荐

  1. 条件分页 分页条件和页参数传递方式一 超链接拼串 方式二 使用查询表单searchForm

    <%-- Created by IntelliJ IDEA. User: jie Date: 2019/5/10 Time: 20:00 To change this template use ...

  2. ubuntu 设置字符集 locale(解决乱码问题)

    1.locale 查看现在的locale配置环境 2.localepurge 配置需要的locale(如果没有这个命令,用apt-get install localepurge安装) 3.locale ...

  3. 搞定vscode编写java

    下载vscode: 地址: https://code.visualstudio.com/ 安装插件 我这里下载的是绿色版,所以解压后 向桌面发送一个快捷方式 找到VS Code 的快捷方式位置: 右键 ...

  4. Python web前端 10 bootstrp

    Python web前端 10 bootstrp 1.媒体查询 <style> *{ margin: 0; padding: 0; } div{ width: 110px; height: ...

  5. Ionic中基于js的扩展(指令和服务)来实现各种效果

    1.ion-header-bar ion-footer-bar ion-content align-title='left/ritght/center <body> <ion-hea ...

  6. 【填坑】loj6159. 「美团 CodeM 初赛 Round A」最长树链

    水一水 枚举各个质数,把是这个数倍数的点留下,跑直径,没了 #include <bits/stdc++.h> using namespace std; int h,t,n,p,q,M,N; ...

  7. poj3728The merchant树剖+线段树

    如果直接在一条直线上,那么就建线段树 考虑每一个区间维护最小值和最大值和答案,就符合了合并的条件,一个log轻松做 那么在树上只要套一个树剖就搞定了,多一个log也不是问题 注意考虑在树上的话每一条链 ...

  8. 朱晔的互联网架构实践心得S2E7:漫谈平台架构的工作(基础架构、基础服务、基础平台、基础中间件等等)

    前言 程序开发毕竟还不是搬砖这种无脑体力劳动,需要事先有标准,有架构,有设计,绝对不是新公司今天创立,明天就可以开始编码的.其实很多公司在起步的时候没有财力和资源建设独立的基础架构或平台架构部门,甚至 ...

  9. 《四 spring源码》手写springioc框架

    手写SpringIOCXML版本 /** * 手写Spring专题 XML方式注入bean * * * */ public class ClassPathXmlApplicationContext { ...

  10. Spring 顾问

    1.名称匹配方法切入点顾问 接口:ISomeService public interface ISomeService { public void doSome(); public void doSe ...