1.多态性:
多态性是指发出同样的消息被不同类型的对象接收时可能导致完全不同的行为
实现方式:函数重载,运算符重载,虚函数
2.运算符重载:
将指定运算符转化为对运算符函数的调用,运算对象转化为运算符函数的实参
可重载符号:除. .* :: ?:之外都可重载
重载规则:1.只可重载已有的 2.不改变运算符的优先级和结合性以及操作数个数 3.包含自定义类型
重载形式:类成员函数和友元函数(全局函数)
#include <iostream>
using namespace std;
class Person
{
friend ostream& operator<<(ostream& cout, Person& p);
private:
int m_A;
int m_B;
public:
Person(int a, int b) :m_A(a), m_B(b) {}
Person& operator++()//前置++
{
m_A++;
m_B++;
return (*this);
}
Person operator++(int)//后置++,Person++(0);
{
Person tmp = *this;
++(*this);
return tmp;
}
};
ostream& operator<<(ostream& cout, Person& p)//友元函数重载,左移运算符一般只能全局友元
{
cout << "m_A=" <<p.m_A << endl;
cout << "m_B=" << p.m_B << endl;
return cout;
}
int main()
{
Person p1(10, 10);
p1++;
cout << p1;
++p1;
cout << p1;
return 0;
}
//运行结果:
//m_A = 11
//m_B = 11
//m_A = 12
//m_B = 12
#include <iostream>
using namespace std;
class Person
{
private:
int* m_A;
public:
Person(int a)
{
m_A = new int(a);
}
Person& operator=(Person& p)//赋值号重载,如果有指针,一般需要重载为深复制,避免堆区数据重复释放
{
m_A = new int(*p.m_A);
return *this;
}
void showPerson()
{
cout << "*m_A=" << *m_A << endl;
}
~Person()
{
if (m_A != NULL)
{
delete m_A;
m_A = NULL;
}
}
};
int main()
{
Person p1(19), p2(59);
p1 = p2;
p1.showPerson();
return 0;
}
//运行结果:
//* m_A = 59
3.虚函数:
虚函数是动态绑定的基础,是非静态的成员函数,在声明原型前加virtual,但实现时不能加virtual
继承性:基类声明的虚函数,派生类中自动为虚函数
本质:不是重载声明是覆盖,父类虚函数会有一个虚函数(表)指针vfptr,指向虚函数表vftable,子类重写函数会替换虚函数表中的内容,不同子类不同覆盖
调用方式:父类指针或引用指向子类的对象,但是只能使用父类的成员
#include <iostream>
using namespace std;
class Base
{
private:
int m_A;
int m_B;
public:
Base(int a,int b):m_A(a),m_B(b){}
virtual void show()
{
cout << "Base的函数调用" << endl;
}
};
class Son :public Base
{
private:
int m_C;
public:
Son(int a,int b,int c):m_C(c),Base(a,b){}
void show()//虚函数重写,发生覆盖
{
cout << "Son的函数调用" << endl;
}
};
int main()
{
Base b1(19, 39);
b1.show();
Son s1(10, 20, 30);//发生覆盖
Base& b2 = s1;
b2.show();
return 0;
}
//运行结果:
//Base的函数调用
//Son的函数调用
虚析构,父类指针调用析构时只能走父类的析构函数,为了调用子类析构函数,应该把父类析构函数改为虚函数,子类重写
4.纯虚函数
拥有纯虚函数的类称为抽象类,抽象类无法实例化对象,子类必须重写纯虚函数,否则也是抽象类,构造函数不能是虚函数,析构函数可以。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};
class Son :public Base
{
public:
void show()
{
cout << "hello world" << endl;
}
};
int main()
{
//Base b1;错误
Son s;
s.show();
return 0;
}
//运行结果:
//hello world