软件设计师——案例分析C++版
代码是直接feishu复制过来的,格式有些不好看,可参考:https://xcnufxf8fowu.feishu.cn/wiki/IND4wNs6yiaUuskhxzdciRGyncf?from=from_copylink
新手小白,自己的笔记,网上大多是java的,给需要速通的伙伴一点点参考。多刷题一边问一遍做。
1、解释一下C++中的对象、消息、类、继承、多态
(1)类
C 语言主要是“数据 + 函数分开写”; C++ 可以把“数据 + 操作这些数据的函数”打包在一起,这个包就叫类。
| C语言 | C++ |
| struct Student { char name[20]; int age; double score; }; | class Student { public: string name; int age; double score; void showInfo() { cout << name << " " << age << " " << score << endl; } }; |
这里的Student就是一个类。不仅有数据,含有函数,也可以理解为类 = 一种自定义的数据类型。
(2)对象
对象:来自于类,根据类创建出来的具体东西
Student s1;
这个就是一个对象,类是学生这个概念,而对象指代的具体某一个学生。
Student s1;
s1.name = "张三";
s1.age = 20;
s1.score = 90.5;
Student s2;
s2.name = "李四";
s2.age = 21;
s2.score = 88;
(3)消息
C++中一般说成调用对象的成员函数
s1.showInfo();
对象接收消息并执行对应行为。
(4)继承
继承:让一个类复用另一个类的代码。
多态:同一个函数调用,不同对象表现不同的结果。
class Person { public: string name; int age; void introduce() { cout << "我是一个人" << endl; } }; class Student { public: string name; int age; string school; void introduce() { cout << "我是一个学生" << endl; } };
如果不用继承的话名字和年龄会出现重复。
class Student : public Person { public: string school; void study() { cout << "我在学习" << endl; } };
这里的意思是Student继承了Person
继承的基本格式:
class 子类 : public 父类 { // 子类自己的内容 };
class Animal { public: string name; void eat() { cout << "动物在吃东西" << endl; } }; class Dog : public Animal { public: void bark() { cout << "狗在叫" << endl; } };
Dog d; d.name = "小黑"; d.eat(); d.bark();
(5)多态
经典含义:同一个函数调用,根据对象的真实类型,执行不同版本的函数。
#include <iostream> using namespace std; class Animal { public: virtual void speak() { cout << "动物发出声音" << endl; } }; class Dog : public Animal { public: void speak() override { cout << "狗:汪汪" << endl; } }; class Cat : public Animal { public: void speak() override { cout << "猫:喵喵" << endl; } }; int main() { Animal* p; Dog d; Cat c; p = &d; p->speak(); p = &c; p->speak(); return 0; }
多态通常的三个条件:有继承关系、父类函数加virtual、用父类指针或者父类引用调用。
override:意思是:我明确告诉编译器,这个函数是重写父类虚函数
2、纯虚函数和抽象类(析构函数)
纯虚函数:父类只规定“必须有这个功能”,但不写具体实现
抽象类:含有纯虚函数的类,不能直接创建对象。
析构函数:对象销毁时自动调用的函数,用来清理资源。
(1)纯虚函数
virtual viod show() const=0;
纯虚函数格式如上。
(2)抽象类
class Animal { public: virtual void speak() = 0; };
抽象类不能直接创建对象,Animal a 是错误的,因为Animal里面有一个函数没有具体实现。
#include <iostream> using namespace std; class Animal { public: virtual void speak() = 0; }; class Dog : public Animal { public: void speak() override { cout << "狗:汪汪" << endl; } }; class Cat : public Animal { public: void speak() override { cout << "猫:喵喵" << endl; } }; void makeSound(Animal& animal) { animal.speak(); } int main() { Dog dog; Cat cat; makeSound(dog); makeSound(cat); return 0; }
(3)析构函数
class Student { public: Student() { cout << "构造函数:对象创建了" << endl; } ~Student() { cout << "析构函数:对象销毁了" << endl; } };
析构函数的名字是:
~类名()
完整格式:
class Student { public: ~Student() { // 清理代码 } };
析构函数:没有返回值,函数名是~类名,不能有参数,一个类只能有一个析构函数,对象销毁自动调用。
正确抽象类的写法:
class Animal { public: virtual void speak() = 0; virtual ~Animal() = default; };
完整示例:纯虚函数+抽象类+虚析构
#include <iostream> using namespace std; class Animal { public: virtual void speak() = 0; virtual ~Animal() { cout << "Animal 析构" << endl; } }; class Dog : public Animal { public: void speak() override { cout << "狗:汪汪" << endl; } ~Dog() { cout << "Dog 析构" << endl; } }; class Cat : public Animal { public: void speak() override { cout << "猫:喵喵" << endl; } ~Cat() { cout << "Cat 析构" << endl; } }; int main() { Animal* a1 = new Dog(); Animal* a2 = new Cat(); a1->speak(); a2->speak(); delete a1; delete a2; return 0; }
输出
狗:汪汪 猫:喵喵 Dog 析构 Animal 析构 Cat 析构 Animal 析构
知识点就到这吧,上题
1、Facade,外观模式,是一种通过为多个复杂子系统提供一个一致的接口,使这些子系统更加容易被访问的模式。
以医院为例,就医时患者需要与医院不同的职能部门交互,完成挂号、门诊、取药等操作。为了简化就医流程,设置了一个接待员岗位,代患者完成上述就医步骤,患者只需要与接待员交互即可。
#include <iostream> #include <string> using namespace std; class Patient { public: __(1)__; }; class Disposer { public: __(2)__; }; class Registry : public Disposer { // 挂号 public: void dispose(Patient *patient) { cout << "I am registering...." << patient->getName() << endl; } }; class Doctor : public Disposer { // 医生门诊 public: void dispose(Patient *patient) { cout << "I am diagnosing...." << patient->getName() << endl; } }; class Pharmacy : public Disposer { // 取药 public: void dispose(Patient *patient) { cout << "I am giving medicine...." << patient->getName() << endl; } }; class Facade { private: Patient *patient; public: Facade(Patient *patient) { this->patient = patient; } void dispose() { Registry *registry = new Registry(); Doctor *doctor = new Doctor(); Pharmacy *ph = new Pharmacy(); registry->dispose(patient); doctor->dispose(patient); ph->dispose(patient); } }; class ConcretePatient : public Patient { private: string name; public: ConcretePatient(String name) { this->name = name; } String getName() { return name; } }; int main() { Patient *patient = __(3)__; __(4)__ f = __(5)__; __(6)__; return 0; }第一空:virtual string getName() = 0
第二空:virtual void dispose(Patient *patient) = 0
第三空:Patient *patient =(3); 说明要用父类指针指向一个具体病人对象。但是Patient是抽象类,不能直接写 new Patient(),因为抽象类不能够实例化,所以应该创建它的子类对象:new ConcretePatient("Zhangsan")
第四空和第五空要创建一个Facade对象,前面用了指针方式创建Facade,这里也可以用指针形式创建:Facade* f = new Facade(patient)
接下来就是调用成员函数dispose
第六空答案就应该是f->dispose()
