1. There is a student class, including the student’s name, grades, and requirements:
- Design a friend function compare() to compare the grade of two students.
- Define an object array in the main() function to store the input student data, and find the student with the highest score and the lowest score.
#include <bits/stdc++.h>
using namespace std;
class student {
friend bool compare(student* a, student* b);
private:
string name;
int grades;
string requirements;
public:
student(string name, int grades, string requirements);
~student();
string getName() {
return this->name;
}
};
student::student(string name, int grades, string requirements) {
this->name = name;
this->grades = grades;
this->requirements = requirements;
}
student::~student() {
}
bool compare(student* a, student* b) {
return a->grades > b->grades;
}
int main() {
int n;
cin >> n;
student* stu[1000];
for (int i = 1; i <= n; i++) {
string name;
int grades;
string requirements;
cin >> name >> grades >> requirements;
stu[i] = new student(name, grades, requirements);
}
sort(stu + 1, stu + n + 1, compare);
cout << "The highest score: " << stu[1]->getName() << endl;
cout << "The lowest score: " << stu[n]->getName() << endl;
return 0;
}
2. Define an abstract class Shape, including a pure virtual function perimeter, whose function is to calculate the perimeter of the graph. There are three classes derived from Shape:
- Triangle, the data member includes the length of three sides (a, b, c);
- Rectangle (rectangle), data members include width (width) and height (height);
- Circle, the data member is a radius.
- Reasonably use polymorphism to realize the perimeter function to calculate the perimeter of triangles, rectangles, and circles.
- Create triangle objects, rectangle objects and circle objects in main () and display their information.
#include <bits/stdc++.h>
using namespace std;
class Shape {
public:
virtual double perimeter() = 0;
};
class Triangle : public Shape {
private:
int length;
public:
Triangle(int length) : length(length) {}
double perimeter() {
return 3 * length;
}
};
class Rectangle : public Shape {
private:
int width;
int height;
public:
Rectangle(int width, int height) : width(width), height(height) {}
double perimeter() {
return 2 * (width + height);
}
};
class Circle : public Shape {
private:
int radius;
public:
Circle(int radius) : radius(radius) {}
double perimeter() {
return 2 * M_PI * radius;
}
};
int main() {
Shape* triangle = new Triangle(1);
Shape* rectangle = new Rectangle(2, 3);
Shape* circle = new Circle(1);
cout << triangle->perimeter() << endl;
cout << rectangle->perimeter() << endl;
cout << circle->perimeter() << endl;
return 0;
}
3. Define the Person class. The Teacher class and the Cadre class are derived from Person. Requirements are as follows:
- Data members:
- The data members included in the Person class include name, age, and gender.
- Include data members in the Teacher class: position.
- Include data members in the Cadre class: work, salary.
- Member function:
- Define member functions in the class body (including construction and destructor functions according to the actual situation)
- Each class has a display information function (Show)
- Create a Teacher object and a Cadre object in main() and display their information.
#include <bits/stdc++.h>
using namespace std;
class Person {
private:
string name;
int age;
string gender;
public:
Person(string name, int age, string gender);
~Person();
void show();
};
Person::Person(string name, int age, string gender) : name(name), age(age), gender(gender) {
}
Person::~Person() {
}
class Teacher : public Person {
private:
string position;
public:
Teacher(string name, int age, string gender, string position);
~Teacher();
void show();
};
Teacher::Teacher(string name, int age, string gender, string position) : Person(name, age, gender), position(position) {
}
Teacher::~Teacher() {
}
class Cadre : public Person {
private:
string work;
string salary;
public:
Cadre(string name, int age, string gender, string work, string salary);
~Cadre();
void show();
};
Cadre::Cadre(string name, int age, string gender, string work, string salary) : Person(name, age, gender), work(work), salary(salary) {
}
Cadre::~Cadre() {
}
void Person::show() {
cout << name << " " << age << " " << gender << " ";
}
void Teacher::show() {
Person::show();
cout << position << endl;
}
void Cadre::show() {
Person::show();
cout << work << " " << salary << endl;
}
int main() {
Teacher* teacher = new Teacher("xiaoming", 18, "male", "teacher");
Cadre* cadre = new Cadre("xiaohong", 20, "female", "student", "1000");
teacher->show();
cadre->show();
return 0;
}
4. Define a base class Animal, which contains two private data members, one is the name of the animal (for example, “Fido” or “Yogi”), and the other is the weight of the animal.
- This class also contains a public member function who(), which can display the animal’s name and weight.
- Using Animal as a public base class, derive two classes Lion and Aardvark.
- Write a main() function to create Lion and Aardvark objects (“Leo”, 400 points; “Algernon”, 50 points).
- Calling the who() member for the derived class object indicates that the who() member is inherited in the two derived classes.
#include <bits/stdc++.h>
using namespace std;
class Animal {
private:
string name;
int weight;
public:
void who() {
cout << name << " " << weight << endl;
}
Animal(string name, int weight);
};
Animal::Animal(string name, int weight) {
this->name = name;
this->weight = weight;
}
class Lion : public Animal {
public:
Lion(string name, int weight);
};
Lion::Lion(string name, int weight) : Animal(name, weight) {
}
class Aardvark : public Animal {
public:
Aardvark(string name, int weight);
};
Aardvark::Aardvark(string name, int weight) : Animal(name, weight) {
}
int main() {
Lion* lion = new Lion("Leo", 400);
Aardvark* aardvark = new Aardvark("Algernon", 50);
lion->who();
aardvark->who();
return 0;
}
筆記
派生類
- 派生類定義
- 派生類定義格式
-
class 派生類名 : 繼承方式 基類名 { // 派生類新增的數據成員和成員函數 };
- 三種繼承方式
- public: 公有繼承
- private: 私有繼承
- protected: 保護繼承
- 從繼承源上分
- 單繼承:指每個派生類只直接繼承了一個基類的特征
-
class B : public A {};
- 多繼承:指多個基類派生出一個派生類的繼承關係,多繼承的派生類直接繼承了不止一個基類的特征
-
class C : public A, protected B {};
- 派生類訪問控制
- 基類
-
class A { public: int a; protected: int b; private: int c; };
-
- 公有繼承
-
class B : public A { public: int a; protected: int b; 不可访问: int c; };
-
- 保護繼承
-
class B : public A { protected: int a; int b; 不可访问: int c; };
-
- 私有繼承
-
class B : public A { private: int a; int b; 不可访问: int c; };
-
虛函數
多態簡單的說就是允許將子類類型的指針賦值給父類類型的指針
有如下代碼
#include <bits/stdc++.h>
using namespace std;
class Animal {
public:
void speak() {
cout << "animal is speaking" << endl;
}
};
class Cat : public Animal {
public:
void speak() {
cout << "cat is speaking" << endl;
}
};
class Dog : public Animal {
public:
void speak() {
cout << "dog is speaking" << endl;
}
};
void doSpeak(Animal& animal) {
animal.speak();
}
int main() {
Cat cat;
doSpeak(cat);
return 0;
}
我們先定義了一個基類,基類裡面有一個speak函數,然後有許多的類繼承該基類,生成了許多個派生類,每個派生類的speak都有重寫過
現在我們希望只聲明一個函數,不同的派生類調用時執行的是自己的成員函數。即貓調用時應該是貓在說話,狗調用時應該是狗在說話
但是按照上述寫法,輸出的是animal is speaking
因為參數裡面的類是Animal,故地址早就綁定好了
地址早就綁定了,屬於靜態聯編
如果想調用小貓說話,這個時候函數的地址就不能早綁定好
而是在運行階段再去綁定函數地址,屬於地址晚綁定,叫動態聯編
也就是說父類調用了子類的成員函數
那麼怎樣去動態聯編呢
只要在類的成員函數前面加上一個virtual,這個函數的本質就變成了虛函數
派生類的成員函數前加不加virtual均可
再運行後,輸出的就是cat is speaking了
這樣也就是說運行時會編譯器會動態地去找傳入的對象,再去綁定地址
修改後的代碼如下
#include <bits/stdc++.h>
using namespace std;
class Animal {
public:
virtual void speak() {
cout << "animal is speaking" << endl;
}
};
class Cat : public Animal {
public:
void speak() {
cout << "cat is speaking" << endl;
}
};
class Dog : public Animal {
public:
void speak() {
cout << "dog is speaking" << endl;
}
};
void doSpeak(Animal& animal) {
animal.speak();
}
int main() {
Cat cat;
doSpeak(cat);
return 0;
}
抽象類和純虛函數
在設計時,嘗嘗希望基類僅僅作為其派生類的一個接口
這就是說,僅想對基類進行向上類型轉換,使用它的接口,而不希望用戶實際的創建一個基類的對象
同時創建一個純虛函數允許接口中放置成員原函數,而不一定要提供一段可能對這個函數毫無意義的代碼
做到這點,可以在基類中加入至少一個純虛函數,使得基類稱為抽象類
抽象类的子类必须要重写父类中的纯虚函数,否则也属于抽象类,无法实例化
语法:
virtual int func() = 0;
多態的實例:加減乘法計算器
#include <bits/stdc++.h>
using namespace std;
class AbstractCalculator {
public:
virtual int getResult() = 0;
int m_A;
int m_B;
};
class AddCalculator : public AbstractCalculator {
public:
virtual int getResult() {
return m_A + m_B;
}
};
class SubCalculator : public AbstractCalculator {
public:
virtual int getResult() {
return m_A - m_B;
}
};
class MulCalculator : public AbstractCalculator {
public:
virtual int getResult() {
return m_A * m_B;
}
};
class Test : public AbstractCalculator {
int getResult() { return 0; };
};
int main() {
AbstractCalculator* calculator = new AddCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
delete calculator;
calculator = new SubCalculator;
calculator->m_A = 100;
calculator->m_B = 200;
cout << calculator->getResult() << endl;
return 0;
}