第八章 多态性
注:下述代码中省略了 1 2
| #include <iostream> using namespace std;
|
8-4
请编写一个计数器Counter类,对其重载运算符“+”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Counter { private: int num; public: Counter() :num(0) {} Counter(int n) :num(n) {} void SetNum(int n) { num = n; } void show() { cout << num << endl; } int operator +(Counter& c) { return num + c.num; } };
|
8-5
编写一个哺乳动物类Mammal,再由此派生出狗类Dog,二者都声明speak()成员函数,该函数在基类中被声明为虚函数,声明一个Dog类的对象,通过此对象调用speak函数,观察运行结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Mammal { public: virtual void speak() { cout << "mammal sepak" << endl;
} };
class Dog { public: void speak() { cout << "dog speak" << endl; } };
int main() { Mammal m1; Dog d; Mammal* m2 = &d; m1.speak(); m2->speak(); d.speak(); }
|
8-6
请编写一个抽象类Shape,在此基础上派生出类Rectangle和Circle,二者都有计算对象面积的函数getArea()、计算对象周长的函数getPerim()。
抽象类Shape的声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Shape { public: virtual void getArea() const = 0; virtual void getPerim() const = 0; virtual ~Shape(){} private: }; ```
### 派生类Rectangle和Circle的声明 ```cpp
class Rectangle :public Shape { public: Rectangle():length(0), width(0){} Rectangle(double x, double y):length(x), width(y){} virtual void getArea() const override { cout << "Rectangle's area is: " << length * width << endl; } virtual void getPerim() const override { cout << "Rectangle's perim is: " << 2 * (length + width) << endl; } private: double length, width; };
const double PI = 3.1415926; class Circle :public Shape { public: Circle() : radius(0) {} Circle(double r) : radius(r) {} virtual void getArea() const override { cout << "Circle's area is : " << PI * radius * radius << endl; } virtual void getPerim() const override { cout << "Circle's perim is : " << 2 * PI * radius << endl; } private: double radius; };
|
main()函数测试
1 2 3 4 5 6 7 8 9 10
| int main() { Shape* shape[2]; shape[0] = new Circle(2); shape[1] = new Rectangle(2.5, 4); for (int i = 0; i < 2; i++) { shape[i]->getArea(); shape[i]->getPerim(); } return 0; }
|
8-7
对类Point重载“++”(自增)、“--”(自减)运算符,要求同时重载前缀和后缀形式。
题目中并没有指出对于Point类重载的自增/自减运算符要具体实现什么功能,在这里我将其实现为将对象的横纵坐标各加/减一。
Point类的声明
注:由于类Point是本书示例中常用的一个类,我将其声明单独写在了一份头文件里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #pragma once class Point { public: Point() :x(0), y(0) {}; Point(double x, double y) :x(x), y(y) {}; double getx(); double gety(); void setx(double newx); void sety(double newy); Point& operator ++(); Point operator ++ (int); Point& operator --(); Point operator -- (int); friend Point operator + (Point p1, Point p2); void show(); private: double x, y; };
|
Point类的实现(自增/自减运算符重载的实现在这里定义)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include "point.h" #include<iostream> using namespace std; double Point::getx(){ return x; }
double Point::gety(){ return y; }
void Point::setx(double newx){ x = newx; }
void Point::sety(double newy){ y = newy; }
Point& Point::operator++(){ setx(getx() + 1); sety(gety() + 1); return * this; }
Point Point::operator++(int){ Point old = *this; ++(*this); return old; }
Point& Point::operator--(){ setx(getx() - 1); sety(gety() - 1); return *this; }
Point Point::operator--(int){ Point old = *this; --(*this); return old; }
void Point::show(){ cout << "(" << x << "," << y << ")" << endl; }
Point operator+(Point p1, Point p2) { return Point(p1.x + p2.x, p1.y + p2.y); }
|
main()函数进行测试
1 2 3 4 5 6 7 8 9
| #include"point.h" int main() { Point p(0, 0); (p++).show(); (++p).show(); (p--).show(); (--p).show(); return 0; }
|
8-8
定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass有成员函数fn1()、fn2(),fn1()是虚函数;DerivedClass也有成员函数fn1()、fn2()。在主函数中声明一个DerivedClass的对象,分别用BaseClass和DerivedClass的指针指向DerivedClass的对象,并通过指针调用fn1()、fn2(),观察运行结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class BaseClass { public: virtual void fn1() { cout << "Base fn1()" << endl; } void fn2() { cout << "Base fn2()" << endl; } };
class DerivedClass :public BaseClass { public: void fn1() { cout << "Derived fn1()" << endl; } void fn2() { cout << "Derived fn2()" << endl; } };
int main() { DerivedClass DC; BaseClass* bp = &DC; DerivedClass* dp = &DC; bp->fn1(); bp->fn2(); dp->fn1(); dp->fn2(); return 0; }
|
8-9
请编写程序定义一个基类BaseClass,从它派生出类DerivedClass。在BaseClass中声明虚析构函数,在主函数中将一个动态分配的DerivedClass的对象地址赋给一个BaseClass的指针,然后通过指针释放对象空间,观察程序运行过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class BaseClass { public: virtual ~BaseClass() { cout << "Destructing BaseClass..." << endl; } };
class DerivedClass :public BaseClass { public: ~DerivedClass() { cout << "Destructing DerivedClass..." << endl; } };
int main() { BaseClass* bc = new DerivedClass; delete bc; return 0; }
|
8-10
编写程序定义类Point,有数据成员x,y,为其定义友元函数实现重载“+”。
此题目已在8-7中实现,参考8-7代码即可。