多态:
#include<iostream>
#include<string>
using namespace std;
class father {
public:
father(string name,int money):name(name),money(money){}
void print()
{
cout << name << ":" << money << endl;
}
protected:
string name;
int money;
};
class son :public father{
public:
son(string nameSon,string fatherName,int money):nameSon(nameSon),father(fatherName,money){}
void print()
{
cout << nameSon << ":" << money << endl;
}
protected:
string nameSon;
};
int main()
{
//父类调用
father* pF = new father("爸爸", 10000);
pF->print();
//子类调用
son* pS = new son("儿子", "爸爸",10000000);
pS->print();
//父类指针用子类初始化
father* ppF = new son("儿子", "爸爸",111);
ppF->print();
//子类用父类构造 错误
//son* ppS = new father("子->父", "222");
}
输出结果:
从输出结果可知,父类指针用子类初始化的时候,调用的是父类的函数(这一现象称为多态)。
但是如果父类中函数采用virtual修饰了,这里就调用子类。
多态两要素:
1、存在虚函数
2、存在父类指针被子类对象初始化(存在引用)
虚函数表:类中所定义的虚函数都是放到一个指针中,该指针指向虚函数表
#include<iostream>
#include<string>
using namespace std;
class father {
public:
father() {}
father(int age) :age(age) {};
virtual void printA() { cout << "father::printA" << endl; }
virtual void printB() { cout << "father::printB" << endl; }
protected:
int age;
};
class son :public father{
public:
son() {}
son(int ageSon,int age):ageSon(ageSon),father(age){}
void printB() { cout << "son::printB" << endl; }
protected:
int ageSon;
};
int main()
{
typedef void(*Function)();
//father Fobject;
father* pF = new son;
long* ptr = (long*)pF;
long* pptr = (long*)*ptr;
Function pFuncA = (Function)pptr[0];
Function pFuncB = (Function)pptr[1];
pFuncA();
pFuncB();
return 0;
}
父类中函数含有virtual的调用:
#include<iostream>
#include<string>
using namespace std;
class father {
public:
father(int age) :age(age) {};
virtual void printA() { cout << "father::printA" << endl; }
virtual void printB() { cout << "father::printB" << endl; }
protected:
int age;
};
class son :public father{
public:
son(int ageSon,int age):ageSon(ageSon),father(age){}
void printB() { cout << "son::printB" << endl; }
protected:
int ageSon;
};
int main()
{
father* pF = new son(18,48);
pF->printA();
pF->printB();
return 0;
}
可知,当带有virtual的时候,父类指针用子类初始化,当父类和子类有一样的函数,会调用子类的函数
纯虚函数:
#include<iostream>
#include<string>
using namespace std;
//抽象类
class stack
{
//纯虚函数
public:
virtual~stack()
{
}
virtual void push(int data) = 0;
virtual void pop() = 0;
virtual int getTop() = 0;
virtual int sizeStack() const = 0;
virtual bool isEmpty() const = 0;
};
class pStackA :public stack{
public:
pStackA(int Memory)
{
size = 0;
this->stackMemory = (int*)malloc(sizeof(int) * Memory);
}
//抽象类中的纯虚函数必须在其派生的类中全部实现
void push(int data) {
stackMemory[++size] = data;
}
void pop() {
--size;
}
int getTop() {
return stackMemory[size];
}
int sizeStack() const {
return size;
}
bool isEmpty() const {
return size == 0;
}
//由于父类用派生类初始化产生的内存无法释放,所以在父类中产生了一个纯虚析构函数
~pStackA()
{
delete[] stackMemory;
cout << "调用析构函数" << endl;
}
protected:
int size;
int* stackMemory;
};
int main()
{
//抽象类不能创建对象,但是可以创建对象指针。用其派生类来初始化对象指针。
stack* pstack = new pStackA(10);
pstack->push(10);
pstack->push(3);
while (!pstack->isEmpty())
{
cout << pstack->getTop() << endl;
pstack->pop();
}
return 0;
}