实验四 多态和动态绑定
一.实验目的
1.理解并掌握运算符重载为成员函数的原理和方法;
2.理解并掌握运算符重载为非成员函数的原理和方法;
3.理解并掌握虚函数的原理和使用方法;
二. 实验内容
1. 理解并掌握运算符重载为成员函数的原理和方法
1.根据下列复数类的定义,请将复数的乘法重载为类的成员函数,以实现在主函数中能够直接进行复数的乘法运算。
#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 &c2) const; //运算符+重载成员函数
Complex operator - (const Complex &c2) const; //运算符-重载成员函数
void display() const; //输出复数
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex Complex::operator + (const Complex &c2) const { //重载运算符函数实现
return Complex(real + c2.real, imag + c2.imag); //创建一个临时无名对象作为返回值
}
Complex Complex::operator - (const Complex &c2) const { //重载运算符函数实现
return Complex(real - c2.real, imag - c2.imag); //创建一个临时无名对象作为返回值
}
void Complex::display() const {
cout << "(" << real << ", " << imag << ")" << endl;
}
int main() { //主函数
Complex c1(5, 4), c2(2, 10), c3; //定义复数类的对象
cout << "c1 = "; c1.display();
cout << "c2 = "; c2.display();
c3 = c1 - c2; //使用重载运算符完成复数减法
cout << "c3 = c1 - c2 = "; c3.display();
c3 = c1 + c2; //使用重载运算符完成复数加法
cout << "c3 = c1 + c2 = "; c3.display();
return 0;
}
完成以下内容:仿照上述的复数加减法运算程序,增加复数的乘法运算( (a+bi)*(c+di)=(ac-bd)+(ad+bc)i)重载,并在主函数中进行测试(c3=c1*c2)。给出程序的完整源代码,并粘贴运行结果截图。
#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 &c2) const; //运算符+重载成员函数
Complex operator - (const Complex &c2) const; //运算符-重载成员函数
Complex operator * (const Complex &c2) const;
void display() const; //输出复数
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex Complex::operator + (const Complex &c2) const { //重载运算符函数实现
return Complex(real + c2.real, imag + c2.imag); //创建一个临时无名对象作为返回值
}
Complex Complex::operator - (const Complex &c2) const { //重载运算符函数实现
return Complex(real - c2.real, imag - c2.imag); //创建一个临时无名对象作为返回值
}
Complex Complex::operator * (const Complex &c2) const { //重载运算符函数实现
return Complex(real*c2.real-imag*c2.imag, real*c2.imag+imag*c2.real); //创建一个临时无名对象作为返回值
}
void Complex::display() const {
cout << "(" << real << ", " << imag << ")" << endl;
}
int main() { //主函数
Complex c1(5, 4), c2(2, 10), c3; //定义复数类的对象
cout << "c1 = "; c1.display();
cout << "c2 = "; c2.display();
c3 = c1 - c2; //使用重载运算符完成复数减法
cout << "c3 = c1 - c2 = "; c3.display();
c3 = c1 + c2; //使用重载运算符完成复数加法
cout << "c3 = c1 + c2 = "; c3.display();
c3 = c1 * c2; //使用重载运算符完成复数乘法
cout << "c3 = c1 * c2 = "; c3.display();
return 0;
}
运行结果截图:
2.理解并掌握运算符重载为非成员函数的原理和方法
2.请将上面题目的复数乘法运算重载为复数类的友元函数来实现,具体要求同上一题。
#include <iostream>
using namespace std;
class Complex;
Complex operator + (const Complex &c1, const Complex &c2); //运算符+重载非成员函数
Complex operator - (const Complex &c1, const Complex &c2); //运算符-重载非成员函数
Complex operator * (const Complex &c1, const Complex &c2); //运算符*重载非成员函数
class Complex { //复数类定义
public: //外部接口
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { } //构造函数
friend Complex operator + (const Complex &c1, const Complex &c2); //运算符+重载成员函数
friend Complex operator - (const Complex &c1, const Complex &c2); //运算符-重载成员函数
friend Complex operator * (const Complex &c1, const Complex &c2);
void display() const; //输出复数
private: //私有数据成员
double real; //复数实部
double imag; //复数虚部
};
Complex operator + (const Complex &c1, const Complex &c2){ //重载运算符函数实现
return Complex(c1.real + c2.real, c1.imag + c2.imag); //创建一个临时无名对象作为返回值
}
Complex operator - (const Complex &c1, const Complex &c2){ //重载运算符函数实现
return Complex(c1.real - c2.real, c1.imag - c2.imag); //创建一个临时无名对象作为返回值
}
Complex operator * (const Complex &c1, const Complex &c2){ //重载运算符函数实现
return Complex(c1.real*c2.real-c1.imag*c2.imag, c1.real*c2.imag+c1.imag*c2.real); //创建一个临时无名对象作为返回值
}
void Complex::display() const {
cout << "(" << real << ", " << imag << ")" << endl;
}
int main() { //主函数
Complex c1(5, 4), c2(2, 10), c3; //定义复数类的对象
cout << "c1 = "; c1.display();
cout << "c2 = "; c2.display();
c3 = c1 - c2; //使用重载运算符完成复数减法
cout << "c3 = c1 - c2 = "; c3.display();
c3 = c1 + c2; //使用重载运算符完成复数加法
cout << "c3 = c1 + c2 = "; c3.display();
c3 = c1 * c2; //使用重载运算符完成复数乘法
cout << "c3 = c1 * c2 = "; c3.display();
return 0;
}
运行结果截图:
3. 理解并掌握运算符重载的原理及方法
3.对给定的Point类,请重载++(自增),--(自减)运算符,要求同时重载
前缀和后缀的形式。
#include <iostream>
using namespace std;
class Point
{
public:
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point() { _x = _y = 0; }
int x() { return _x; }
int y() { return _y; }
private:
int _x, _y;
};
//给出前置++:perator++()的实现
Point& Point::operator++()
{
}
//给出后置++:operator++(int)的实现
Point Point::operator++(int)
{
}
//给出前置--:perator--()的实现
Point& Point::operator--()
{
}
//给出后置--:perator--(int)的实现
Point Point::operator--(int)
{
}
int main()
{
Point a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
a++;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
++a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
a--;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
--a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
}
请给出程序完整源代码和运行结果截图。
#include <iostream>
using namespace std;
class Point
{
public:
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point() { _x = _y = 0; }
int x() { return _x; }
int y() { return _y; }
private:
int _x, _y;
};
//给出前置++:perator++()的实现
Point& Point::operator++()
{
_x++;_y++;
return *this;
}
//给出后置++:operator++(int)的实现
Point Point::operator++(int)
{
Point old = *this;
_x++;_y++;
return old;
}
//给出前置--:perator--()的实现
Point& Point::operator--()
{
_x--;_y--;
return *this;
}
//给出后置--:perator--(int)的实现
Point Point::operator--(int)
{
Point old = *this;
_x--;_y--;
return old;
}
int main()
{
Point a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
a++;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
++a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
a--;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
--a;
cout << "a的值为:" << a.x() << " , " << a.y() << endl;
}
运行结果截图:
4. 理解并掌握虚函数的原理和使用方法
4.请编写一个抽象类Shape(其中含有getArea()和getPerim()两个成员函数),类Shape派生出Rectangle和Circle类,Rectangle和Circle类都有计算面积的函数getArea()、计算对象周长的函数getPerim()。请按照题目中的要求完善程序,给出程序源代码,并粘贴运行结果截图。
#include <iostream>
using namespace std;
//完善类Shape的定义
class Shape
{
public:
Shape(){}
~Shape(){}
};
//完善Circle 的定义
class Circle : public Shape
{
public:
Circle(float radius):itsRadius(radius){}
~Circle(){}
private:
float itsRadius;
};
//完善Rectangle的定义
class Rectangle : public Shape
{
public:
Rectangle(float len, float width): itsLength(len), itsWidth(width){};
~Rectangle(){};
private:
float itsWidth;
float itsLength;
};
int main()
{
Shape * sp;
sp = new Circle(5);
cout << "The area of the Circle is " << sp->getArea () << endl;
cout << "The perimeter of the Circle is " << sp->getPerim () << endl;
delete sp;
sp = new Rectangle(4,6);
cout << "The area of the Rectangle is " << sp->getArea() << endl;
cout << "The perimeter of the Rectangle is " << sp->getPerim () << endl;
delete sp;
return 0;
}
#include <iostream>
using namespace std;
const float PI = 3.14;
//完善类Shape的定义
class Shape
{
public:
Shape(){}
~Shape(){}
virtual float getArea()=0;//此处需要定义为纯虚函数,不然不实现函数体会报错
virtual float getPerim()=0;//此处需要定义为纯虚函数,不然不实现函数体会报错
};
//完善Circle 的定义
class Circle : public Shape
{
public:
Circle(float radius):itsRadius(radius){}
~Circle(){}
virtual float getArea();
virtual float getPerim();
private:
float itsRadius;
};
//完善Rectangle的定义
class Rectangle : public Shape
{
public:
Rectangle(float len, float width): itsLength(len), itsWidth(width){};
~Rectangle(){};
virtual float getArea();
virtual float getPerim();
private:
float itsWidth;
float itsLength;
};
float Circle::getArea(){
return itsRadius*itsRadius*PI;
}
float Circle::getPerim(){
return itsRadius*PI*2;
}
float Rectangle::getArea(){
return itsWidth*itsLength;
}
float Rectangle::getPerim(){
return (itsLength+itsWidth)*2;
}
int main()
{
Shape * sp;
sp = new Circle(5);
cout << "The area of the Circle is " << sp->getArea () << endl;
cout << "The perimeter of the Circle is " << sp->getPerim () << endl;
delete sp;
sp = new Rectangle(4,6);
cout << "The area of the Rectangle is " << sp->getArea() << endl;
cout << "The perimeter of the Rectangle is " << sp->getPerim () << endl;
delete sp;
return 0;
}
运行结果截图: