重载与多态
一.运算符重载
定义:运算符重载是对已有运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。例如:
在这样一段程序中,我们对a,b进行加法运算,
# include < iostream >
using namespace std;
class Counter
{public :
Counter() {};
Counter(int i) { count = i; }
private :
int count;
};
int main()
{
Counter a(1),b(2),c;
cout << "a=" << a<
会出现这样的错误
这时候就需要运算符重载
1.1
运算符重载的规则:(1)c++中的运算符大多可以重载,而且只能重载已有运算符。
(2)重载之后运算符优先级和结合性都不会改变。
(3)运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。
运算符重载为类的成员函数的语法形式:
返回类型 operater 运算符{形参表}
{
函数体
}
以非成员函数重载的语法与之相同,但有时访问涉及到私有成员,可以将函数声明为友元函数。例如:
# include < iostream >
using namespace std;
class Counter
{public :
Counter() {};
Counter(int i) { count = i; }
friend Counter operator+(const Counter & c1, const Counter & c2);
friend ostream& operator<< (ostream & cout, Counter&c1);
private :
int count;
};
Counter operator + (const Counter & c1, const Counter & c2) {
return Counter (c1.count+c2.count);
}
ostream& operator<< (ostream & cout, Counter&c1) {
cout << c1.count;
return cout;
}
int main()
{
Counter a(1),b(2),c;
cout << "a=" << a<
结果:
注意:当运算符重载为类的成员函数时,函数的参数比原来的操作个数少一个;重载为非成员函数时参数个数与原操作数相同
1.2运算符重载成员函数和非成员函数
以将单目运算符++重载为例,
成员函数:
# include< iostream >
using namespace std;
class Complex {
public:
Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
Complex operator++()const;
Complex operator++(int)const;
void display() {
cout<<"real:"<real;
c.imag = this->imag;
return c;
}
Complex Complex:: operator++( int)const{
Complex c=*this;
c.real++;
c.imag++;
return c;
}
int main() {
Complex c1(5, 4), c2, c3;
cout << "c1=";
c1.display();
c2 = ++c1;
cout << "c2=" ;
c2.display();
c3 = c1++;
cout << "c3=" ;
c3.display();
system("pause");
}
在本例中前置与后置最大的不同在于有无形参,其他的与普通的成员函数,没有什么区别只是++这个运算符能做用于不同的对象上,有了更广泛的多态特征。
非成员函数:
因访问私有成员,声明为友元函数
# include< iostream >
using namespace std;
class Complex {
public:
Complex(double r = 0.0, double i = 0.0) :real(r), imag(i) {}
friend Complex operator++(Complex &c1);
friend Complex operator++(Complex &c1,int);
void display() {
cout<<"real:"<
结果:
二.多态
定义:指同样的消息被不同类型对象接受时导致的不同行为。在实现时可以分为静态多态和动态多态。
静态多态:在编译过程中确定了同名操作的具体操作对象,例如重载。
动态多态:运行过程才动态的确定操作针对的对象,例如虚函数。
2.1虚函数
虚函数是动态绑定的基础。是非静态的成员函数。
语法:virtual 函数类型 函数名{形参表};
而运行多态需要满足三个条件:(1)满足赋值兼容规则。(2)声明虚函数。(3)用成员函数调用或者是通过指针或者引用来访问。
例:
# include < iostream >
using namespace std;
class Mammal
{
public:
Mammal() { cout << "constructors Mammal"<Speak();
}
int main()
{
Dog d;
fun(&d);;
system("pause");
return 0;
}
可见函数成员speak()声明为虚函数,覆盖了基类的虚函数如需访问基类使用指针,这样,能够对同一类族中的对象进行统一处理,抽象程度更高,更简洁,高效。
2.2虚析构函数
语法:virtual ~类名();
虚析构函数是为了彻底释放内存,防止内存泄露。例:
# include < iostream >
using namespace std;
class BaseClass
{
public:
virtual~BaseClass() {
cout << "虚函数 ~BaseClass()" << endl;
}
};
class DerivedClass : public BaseClass
{
public:
virtual ~DerivedClass() {
cout << "虚函数 ~DerivedClass()" << endl;
}
};
int main()
{
BaseClass *p= new DerivedClass;
delete p;
system("pause");
}
不设为虚析构函数:
设为虚析构函数: