c++第五次作业

亡梦爱人 提交于 2019-12-02 11:26:08

重载与多态

一.运算符重载

定义:运算符重载是对已有运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。例如:
在这样一段程序中,我们对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<<endl;
cout << "b=" << b << endl;
c = a + b;
cout << "c=" <<c << endl;
system("pause");
return 0;
}

会出现这样的错误


这时候就需要运算符重载

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<<endl;
cout << "b=" << b << endl;
c = a + b;
cout << "c=" <<c << endl;
system("pause");
return 0;
}

结果:

注意:当运算符重载为类的成员函数时,函数的参数比原来的操作个数少一个;重载为非成员函数时参数个数与原操作数相同

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 <<"imag:"<<imag<<endl;
}
private:
double real, imag;
};
Complex Complex ::operator++()const {
Complex c;
(*this)++;
c.real=this->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:"<<real <<"imag:"<<imag<<endl;
}
private:
double real, imag;
};
Complex operator++(Complex &c1) {
Complex c;
c1.real++;
c1.imag++;
c.real= c1.real;
c.imag = c1.imag;
return c;
}
Complex operator++(Complex &c1, int){
Complex c;
c.real = c1.real;
c.imag = c1.imag;
c1.real++;
c1.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");
}

结果:

二.多态

定义:指同样的消息被不同类型对象接受时导致的不同行为。在实现时可以分为静态多态和动态多态。
静态多态:在编译过程中确定了同名操作的具体操作对象,例如重载。
动态多态:运行过程才动态的确定操作针对的对象,例如虚函数。

2.1虚函数

虚函数是动态绑定的基础。是非静态的成员函数。
语法:virtual 函数类型 函数名{形参表};

而运行多态需要满足三个条件:(1)满足赋值兼容规则。(2)声明虚函数。(3)用成员函数调用或者是通过指针或者引用来访问。
例:

 # include < iostream >
using namespace std;
class Mammal
{
public:
Mammal() { cout << "constructors Mammal"<<endl; };
~Mammal() { cout << "destructing Mammal"<<endl; };
virtual void Speak() const { 
    cout << "Mammal sound!\n"; 
}

};
class Dog : public Mammal
{
public:
Dog() { cout << "constructors Dog" << endl; };

~Dog() { cout << "destructing Dog" << endl; };

 void Speak() const {        //覆盖基类的虚函数
    cout << "Dog sound!\n";
}

};
void fun(Mammal*p) {
p->Speak();
}
int main()
{
Dog d;
fun(&d);;
system("pause");
return 0;
}

可见函数成员speak()声明为虚函数,覆盖了基类的虚函数如需访问基类使用指针,这样,能够对同一类族中的对象进行统一处理,抽象程度更高,更简洁,高效。

2.2虚析构函数

语法:virtual ~类名();
虚析构函数是为了彻底释放内存,防止内存泄露

1
1
1
1
1
1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!