基类指针,继承

1.类型决定可以调用的函数范围。(但是显示转化的不一定安全,可能程序崩溃,如基类指针显式转为派生类指针,虽然智能提示有派生类的函数,但实际仍不能调用派生类的函数,必须真实指向派生类对象)所以一般不要转类型,而是改变指针指向
2.实际指向决定最终实际调用的函数。

class A
{
public:
    void f1() { cout << "A::f1" << endl; }           //1.虚函数与普通函数不能重名,在一个类中只能出现一种。
    virtual void vf1() { cout << "A::vf1" << endl; } //1.这里vf1不能是f1  2.虚函数只用声明一次,后续默认全部当成虚函数

    void f2() { cout << "A::f2" << endl; }
    virtual void vf2() { cout << "A::vf2" << endl; }
};
class B : public A
{
public:
    void f3() { cout << "B::f3" << endl; };
    void vf1() { cout << "B::vf1" << endl; } //2.多态,基类类型的指针指向不同的派生类调用对应的函数。此时可去掉,也可不去virtual
    virtual void vf3() { cout << "B::vf3" << endl; }
    virtual void vf2() { cout << "B::vf2" << endl; }
};
class C : public B
{
public:
    virtual void vf3() { cout << "C::vf3" << endl; }
    void f4() { cout << "C::vf4" << endl; }
    void f5() { cout << "C::vf5" << endl; }
    void vf1() { cout << "C::vf1" << endl; } //2.这里仍是虚函数
    //virtual void f4(){cout<<"C::vf4"<<endl;};
};

A->B->C

情况1 static_cast

    A a;
    B b;
    C c;

    A *pa = &a; //2.多态的基类指针
    pa->vf1();  //2.多态正确用法
    //pa->f4();//2.多态只能调用指针本身类型含有的虚函数。
    pa->f1();  //2.多态如果指向的派生类对象,没有指针本身基类的虚函数,则会调用指针本身类型的函数(不一定是,见下面补充)
    pa->vf2(); //2.补充上条,会从基类指针指向的类,向上找最近的此函数。
    B *pb2=NULL;
    B *pb =NULL;
    try
    {
        pb = static_cast<B *>(pa); //3.显示类型转换,注意转换后要赋值给B*类型的对象 4.无法避免错误。
       /// pb->vf3();
        pb2 = dynamic_cast<B *>(pa);//4.仅当对象引用之间转换时捕获到错,而指针则直接变为空指针来保证安全
        //pb2->vf3();
    }
    catch (std::bad_cast &bc)
    {
        std::cerr << "bad_cast caught: " << bc.what() << '\n';  
    };
    //5.const_cast去除const属性。将const引用转换为同类型的非const引用,或将const指针转换为同类型的非const指针
    //5.reinterpret_cast,让编译器按照新的类型去解释,不使用已有转换规则(有也不用),不会报错。
    //5.static_cast则会先尝试用有的转换规则(不含类族),如隐式转换一样(有则用,可以自己写类型转换规则,然后用static_cast进行转换),没有规则,则同样按reinterpret新的类型强行解释。
    //5.dynamic_cast用于类族体系转换,保证安全性,要么抛出异常,要么变为空指针。
    //6.c风格强转,则是等效于static_cast。