virtual 虚函数
class A{
public:
virtual void fun(){
std::cout<<"A"<<endl;
}
};
class B:public A{
public:
void fun(){
std::cout<<"B"<<endl;
}
};
void fun2(A *a){
a->fun();
}
int main() {
A a;
a.fun();//(1)
B b;
b.fun();//(2)
A *ab=new B;
ab->fun();//(3)
fun2(ab);//(4)
}
1.只有指针和引用才能诱发虚函数机制。所以
(1)A
(2)B
2.只有虚函数机制,才会出现继承中,调用子类的函数的性质。
(3)B
(4)B
否则,全部都是在编译期确定下来。具体看下面例子
没有virtual就是编译期确定
class A{
public:
void fun(){
std::cout<<"A"<<endl;
}
void fun3(){
fun();
}
};
class B:public A{
public:
void fun(){
std::cout<<"B"<<endl;
}
// void fun3(){
// fun();
// }
};
void fun2(A *a){
a->fun();
}
int main() {
A *a=new B;
a->fun();//(1)
fun2(a);//(2)
a->func3();//(3)
B *b=new B();
b->fun();//(4)
fun2(b);//(5)
b->fun3();//(6)
}
1.上述所有表达式都是编译期就确定会怎样运行的。
2.只要是A定义的对象(A *a=new B),都以A里的函数来运行
(1)A
(2)A:如果想要运行B的fun,只能自己强制类型转换
(3)A:因为在编译期就已经决定调用A里面的fun了。不会调用子类(如果有fun3()),因为不是virtual
3.B定义的对象也是要听编译期的
(4)B
(5)A:因为参数是A,想要用B要类型转换
(6)A
对这个(6)情况要说明一下,编译期就已经要调用A的fun了,不存在子类重写父类函数这种说法。
如果上面B类中不要注释 fun() 函数,就会调用B的fun(),还是因为编译期决定。