1.编程题:
以下是一个简单的比喻,将多态概念与生活中的实际情况相联系:
比喻:动物园的讲解员和动物表演
想象一下你去了一家动物园,看到了许多不同种类的动物,如狮子、大象、猴子等。现在,动物园里有一位讲解员,他会为每种动物表演做简单的介绍。
在这个场景中,我们可以将动物比作是不同的类,而每种动物表演则是类中的函数。而讲解员则是一个基类,他可以根据每种动物的特点和表演,进行相应的介绍。
具体过程如下:
定义一个基类 Animal,其中有一个虚函数 perform(),用于在子类中实现不同的表演行为。
2.用函数模板实现不同数据类型的交换功能。
#include
using namespace std;
class Animal//定义一个基类动物
{
private:
public:
virtual void perform()=0;
virtual ~Animal(){}
};
class Tiger:public Animal
{
public:
void perform()
{
cout << "老虎表演了猛虎下山" <
void Exchange (T &a,L &b)//不同数据类型之间的交换
{
T temp;
temp=a;
a=static_cast(b);
b=static_cast(temp);
}
//void Exchange(T &a,L &b)
//{
// T temp;
// temp=a;
// a=b;
// b=temp;
//}
int main()
{
cout << "==========第一题===========" << endl;
Animal *p;
Tiger t1;
Monkey m1;
Lion l1;
Elephant e1;
cout << "大家请看" < perform();
p = &m1;
p -> perform();
p = &l1;
p -> perform();
p = &e1;
p -> perform();
delete p;
p=nullptr;
cout << "==========第二题===========" << endl;
int a = 98;
char b = 'a';
cout << a << ' ' << b << endl;
Exchange(a,b);
cout << (char)a << ' ' << (int)b << endl;
return 0;
}
一、菱形继承(家具衍生出沙发和床,沙发床继承沙发和床,形成菱形继承),菱形继承会造成空间浪费
二、虚继承,解决菱形继承空间浪费问题
中间子类的继承方式前 加上 virtual:
#include
using namespace std;
class Jiaju
{
private:
string colour;
public:
Jiaju(){cout << "家具的无参构造" << endl;};
Jiaju(string n):colour(n){ cout << "家具的有参构造" << endl;};
};
class Bed:virtual public Jiaju//虚继承
{
private:
string name;
public:
Bed(){cout << "床的无参构造" << endl;};
Bed(string n,string colour):Jiaju(colour),name(n){cout << "床的有参构造" << endl;};
};
class Sofa:virtual public Jiaju//虚继承
{
private:
int id;
public:
Sofa(){cout << "沙发的无参构造" << endl;};
Sofa(int id,string colour):Jiaju(colour),id(id){cout << "沙发的有参构造" << endl;};
};
class SofaBed:public Sofa,public Bed
{
private:
int age;
public:
SofaBed(){cout << "沙发床的无参构造" << endl;};
SofaBed(int age,string name,int id,string colour):Jiaju(colour),Sofa(id,colour),Bed(name,colour),age(age)
{cout << "沙发床的有参构造" << endl;};
};
int main()
{
SofaBed s2;//先调用公共基类Jiaju的无参构造,再调用第一继承的Sofa的无参构造,再调用第二继承的Bed的无参构造
SofaBed s1(10,"大床",11,"白色");//先显性调用公共基类Jiaju的有参构造,再调用第一继承的Sofa的有参构造,再调用第二继承的Bed的有参构造
return 0;
}
三、多态(多种形态,体现代码中Yuan类有Student和Player两种形态,形成多态)
#include
using namespace std;
class Yuan//父类
{
string name;
int age;
public:
Yuan(){};//无参构造
Yuan(string name,int age):name(name),age(age){};//有参构造
virtual void speek()//虚函数,用于被子类进行重写
{
cout << "你好" << endl;
}
};
class Student:public Yuan//继承Yuan的子类
{
int score;
public:
Student(){};//无参构造
Student(string name,int age,int score):Yuan(name,age),score(score){}//有参构造
void speek()//因为Yuan中也有一个speek函数,所以是对父类函数的重写
{
cout << "老师好" << endl;
}
};
class Player:public Yuan//集成Yuan的子类
{
string gname;
public:
Player(){};//无参构造
Player(string name,int age,string gname):Yuan(name,age),gname(gname){};//有参构造
void speek()//因为Yuan中也有一个speek函数,所以是对父类函数的重写
{
cout << "稳住,我们能赢" << endl;
}
};
int main()
{
Yuan *p;
Yuan y1;
Student s1("张三",18,98);
Player p1("张三",18,"阴阳");
p=&y1;
p->speek();//调用父类中的虚函数
p=&s1;//父类指针指向子类对象
p->speek();//调用子类中的重写后的函数
p=&p1;//父类指针指向子类对象
p->speek();//调用子类中的重写后的函数
return 0;
}
1.虚析构函数
#include
using namespace std;
class Person
{
private:
string name;
int age;
public:
Person(){}
Person(string name,int age):name(name),age(age)
{
cout << "这是Person的有参构造函数" << endl;
}
virtual ~Person()
{
cout << "这是Person的析构函数" << endl;
}
};
class Stu:public Person
{
private:
int score;
public:
Stu(){}
Stu(string name,int age,int score):Person(name,age),score(score)
{
cout << "这是Stu的有参构造函数" << endl;
}
~Stu()
{
cout << "这是Stu的析构函数" << endl;
}
};
int main()
{
//Stu s1("张三",18,90);
Person *p = new Stu("李四",20,88);
delete p;
p=nullptr;
return 0;
}
2.纯虚函数
当父类中虚函数被子类用来重写,且没有定义的意义,这个时候,一般把父类中的虚函数设置成纯虚函数。
virtual 函数返回值类型 函数名(形参列表) = 0; //纯虚函数
四、抽象类
抽象类一般是用来被继承的,它不能实例化出具体的一个对象,抽象类中至少有一个纯虚函数。
如果子类没有对父类的纯虚函数重写,那么子类也是抽象类,不能实例化一个对象
五、模板(示例代码为同类型交换)
#include
using namespace std;
template
void fun(T &a,T &b)
{
T temp;
temp=a;
a=b;
b=temp;
}
int main()
{
int a=10,b=20;
fun(a,b);
cout << a << " " << b << endl;
char c='a',d='b';
fun(c,d);
cout << c << " " << d << endl;
return 0;
}