首先通过一个段代码来分析
#include
class Parent//定义父类
{
public:
Parent(int a = 0)
{
this->a = a;
}
void print() //注意这里没有加virtual
{
std::cout << "我是父类" << std::endl;
//std::cout << "a:" << a << std::endl;
}
protected:
private:
int a;
};
class Child :public Parent //继承父类
{
public:
Child(int b = 0)
{
this->b = b;
}
void print()//与父类重名函数(这是重写)
{
std::cout << "我是子类" << std::endl;
//std::cout << "b:" << b << std::endl;
}
protected:
private:
int b;
};
void HowToPrint(Parent *p) //父类的指针变量
{
p->print();
}
void HowToPrint(Parent &p)//父类的引用变量
{
p.print();
}
void main()
{
Parent p1;
Child c1;
p1.print();//这里毫无疑问打印父类的print()
c1.print();//子类对象的print()
Parent *p = NULL;
p = &p1;
p->print();//调用父类的打印函数
//赋值兼容性原则遇上父类与子类同名函数的时候
p = &c1;//把子类对象赋值给父类的指针(赋值兼容性原则)
p->print();//我靠不是把子类对象地址赋值了吗,竟然调用父类的print();
//赋值兼容性原则遇上父类与子类同名函数的时候
Parent &myp = c1;//(父类变量引用子类
myp.print();//疯了,引用子类,竟然调用了父类的函数*/
HowToPrint(&c1);//将子类地址赋值给父类指针,通过指针调用print(),我靠.竟然打印的也是父类
HowToPrint(&p1);//这里无疑问打印父类print
HowToPrint(c1);//引用之类,调用print竟然也是打印我是父类
HowToPrint(p1);//引用父类,无疑问打印父类
system("pause");
}
这就引出多态的问题呢,嗯哼,接下来我来分析此代码
首先应该了解
定义一个子类与一个父类(子类与父类的函数重名问题
1.C/C++是静态编译性语言
在编译时,编译器自动根据指针类型或引用类型判断指向的是一个什么样的对象
2.编译器没有理由报错
3.于是,编译器认为最安全的做法是编译到父类的print函数(父类与子类都有print()函数)
面向对象新需求
如果我传一个父类对象,执行父类的函数
如果我传一个子类的对象,执行子类的函数,可是编译器不支持我
现象产生原因
赋值兼容性原则遇上函数重写,出现了一个现象
也可以说赋值兼容性原则遇上父类与子类同名函数的时候
1.没有理由报错
2.对被调用函数来说
3.在编译器期间,我就确定了这个函数参数是p及父亲类型
#include
class Parent
{
public:
Parent(int a = 0)
{
this->a = a;
}
//如果想要传入什么类型就打印该类型的参数,就使用virtual关键字,在父类加上了关键字,那么就是动态编译
//子类有与父类重名函数,根据传入类型.来进行选择,而不是根据函数参数(静态编译)进行选择
virtual void print()
{
std::cout << "我是父类" << std::endl;
}
protected:
private:
int a;
};
class Child :public Parent
{
public:
Child(int b = 0)
{
this->b = b;
}
void print()
{
std::cout << "我是子类" << std::endl;
}
protected:
private:
int b;
};
void HowToPrint(Parent *p) //3.在编译器期间,我就确定了这个函数参数是p及父亲类型
{ //在这里C++编译器始终认为p是指向父类的指针变量
p->print();//一句话,有多种效果,多种表现形态吧,,这个功能就是传说中的多态
}
void HowToPrint(Parent &p)
{
p.print();
}
void main()
{
Parent p1;
Child c1;
/*-==p1.print();
c1.print();*/
Parent *p = NULL;
p = &p1;
p->print();
p = &c1;
p->print();
Parent &mypk = p1;
p1.print();
Parent &myp = c1;
myp.print();
HowToPrint(&p1);
//兼容性原则
HowToPrint(&c1);
HowToPrint(p1);
//兼容性原则
HowToPrint(c1);
system("pause");
}