C++ 类调用关系没有virtual就是编译期确定

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(),还是因为编译期决定。

猜你喜欢

转载自blog.csdn.net/yxccc_914/article/details/77709584