内容
1. 函数重载
2. 运算符重载
3. 静态联编 (略
4. 动态联编和虚函数 (略
5. 纯虚函数和抽象类(略
1)封装性、继承性、多态性构成OOP的三大特性。
2)在C++中,多态性分为两种:①静态多态 ②动态多态
3)函数重载和运算符重载属于静态多态。函数重载:相同函数名可以完成不同功能。运算符重载:相同运算符完成不同功能。
4)动态多态是指:程序执行过程中确定的关系,如动态确定函数的调用关系。
5)运行时的多态(动态多态)是通过类的继承和虚函数来实现的。
一 函数重载
C++编译器在处理重载函数的调用时,是根据函数的参数类型和参数个数来区分调用哪个函数的。另外,常成员函数的关键字const也能区分重载函数。
例:定义一个字符串String类,对其构造函数进行重载
#include<iostream>
#include<cstring>
using namespace std;
class String
{
int Length; //字符串长度
char *Strp; //字符串首指针
public:
String(); //重载构造函数1
String(char *s); // 重载构造函数2
String(String &s); // 重载构造函数3
void Print()
{
cout<<"String="<<Strp<<endl;
cout<<"Length="<<Length<<endl;
}
~String(){
if (Strp)delete[]Strp;} //析构函数
};
String::String() //构造函数1:将字符串初始化为空串""
{
Length=0;
Strp=new char[Length+1];
*Strp='0';
}
String::String(char *s) //构造函数2:用s指向的串初始化本类字符串
{
Length=strlen(s);
Strp=new char[Length+1];
strcpy(Strp,s);
}
String::String(String &s) //构造函数3:拷贝构造函数
{
Length=s.Length;
Strp=new char[Length+1];
strcpy(Strp,s.Strp);
}
int main( )
{
char *sp="This is a string.";
String str1; //调用重载构造函数1
String str2(sp); //调用重载构造函数2
String str3(str2); //调用重载构造函数3
str1.Print();
str2.Print();
str3.Print();
}
运行结果
![dffab6b0fff7481012648202043b47f2.png](https://img-blog.csdnimg.cn/img_convert/dffab6b0fff7481012648202043b47f2.png)
二 重载运算符
1)C++中所有的运算符都已预先定义了用法及意义。如:+ - * / = 等,适用于已有的数据类型。
2)已定义的用法及意义是不允许用户改变的。如果用户定义了新的数据类型,希望已定义的运算符能适应新的数据类型,运算符的重载可以达到此目的。
例:
Complex c1, c2, c3;
c3 = add(c1, c2); //以前通过函数实现加法运算
c2.add(c3); // 或通过成员函数实现
c3 = c1 + c2; //通过运算符的重载实现
1. 运算符重载的几点说明
1)可以重载的运算符(42个)
2)不可以重载的运算符(5个)
条件运算符?:
成员访问运算符.
成员指针访问运算符.*
作用域运算符::
求字节数运算符sizeof
3)重载运算符的限制
(1)只能对已有运算符重载,不可臆造新的运算符。
(2)不允许改变运算符的优先级和结合性。
(3)不允许改变运算符的语法结构,如二元运算符只能重载成二元运算符,一元运算符只能重载成一元运算符。
2. 运算符重载的两种方式
1)重载为类的成员函数
以 operator 为关键字,编译器可以很容易将运算符重载函数与其他成员函数区别开来。
在类内定义运算符重载函数的格式为:
<函数返回值类型> operator <重载运算符>( [<参数列表>] )
{ … }
在类外定义运算符重载函数的格式为:
<函数返回值类型> <类名>::operator <重载运算符> ( [<参数列表>] )
{…}
当用成员函数实现运算符的重载时,重载函数的参数个数只能是 0 个或 1 个。分别实现:一元、二元运算符的重载。当成员函数重载二元运算符时,成员函数有一个参数。二元运算的第一个运算量是调用运算符重载函数自身,第二个运算量是成员函数的参数。
注:参数列表中 const修饰函数参数表示传递过来的参数在函数内不可以改变,参数为引用是为了增加效率(免于创建副本)同时防止修改。const+引用为良好习惯。
例:实现复数类的“+”,“-”等重载运算
#include<iostream>
using namespace std;
class Complex
{
double Real, Image;
public:
Complex(double r=0, double i=0) //构造函数
{
Real=r;Image=i;
}
Complex operator+(const Complex &c); //重载二元加法
Complex operator+(double); //重载二元加法
Complex operator-(const Complex &c); //重载二元减法
Complex operator-(double); //重载二元减法
Complex operator-(void); //重载一元负号运算符
Complex operator*(const Complex &c); //重载二元乘法运算符
Complex operator/(const Complex &c); //重载二元除法运算符
void Show()
{
cout<<Real;
if (Image>0)
cout<<"+"<<Image<<"i"; //正数显式输出正号
else
if (Image<0) cout<<Image<<"i"; //负数自动输出负号
cout<<endl;
}
};
Complex Complex::operator +(const Complex &c)
{
return Complex (Real+c.Real, Image+c.Image); }
Complex Complex::operator +(double r)
{
return Complex(Real+r, Image); }
Complex Complex::operator-(const Complex &c)
{
Complex t;
t.Real=Real-c.Real;
t.Image=Image-c.Image;
return t;
}
Complex Complex::operator-(double r)
{
Complex t;
t.Real=Real-r;
t.Image=Image;
return t;
}
Complex Complex::operator-(void)
{
return Complex(-Real, -Image); }
Complex Complex::operator*(const Complex &c)
{
double r,i;
r=Real*c.Real-Image*c.Image;
i=Real*c.Image+Image*c.Real