类继承关系梳理

class base {
public:
    int hello() {
        std::cout << "base::hello" << std::endl;
        return 0;
    }
    int hello(std::string str) {
        std::cout << "base::hello " << str << std::endl;
        return 0;
    }
    int base_func() {
        std::cout << "base::base_func" << std::endl;
        return 0;
    }
    int virtual virtual_func() {
        std::cout << "base::virtual_func" << std::endl;
        return 0;
    }

    int var = 0;
};
class derived : public base {
public:
    //using base::hello;
    int hello() {
        std::cout << "derived::hello" << std::endl;
        return 0;
    }

    int derived_func() {
        std::cout << "derived::derived_func" << std::endl;
        return 0;
    }
    
    int virtual virtual_func() {
        std::cout << "derived::virtual_func" << std::endl;
        return 0;
    }

    int var = 1;
};
int32_t main (int32_t argc, char **argv) {
    //派生类测试
    derived der;
    der.base::hello();//基类
    //der.hello("word");//no matching function for call to 'derived::hello(const char [5])'因为hello被重定义后隐藏了
    der.base::hello("word");//基类 加上作用域后
    //der.hello("word");//基类 或者使用using后也可以执行
    der.base_func();//基类
    der.hello();//派生类
    der.virtual_func();//派生类
    std::cout << "base_ptr->var: " << der.var << std::endl;//派生类

    std::cout << std::endl;

    //基类指针指向派生类对象
    base * base_ptr = &der;
    //base_ptr->derived_func();//'class base' has no member named 'derived_func'因为
    //base_ptr->derived::derived_func();//'derived' is not a base of 'base'
    base_ptr->base::virtual_func();//基类
    base_ptr->virtual_func();//派生类
    std::cout << "base_ptr->var: " << base_ptr->var << std::endl;//基类
    return 0;
}

结果

类继承关系梳理_第1张图片

一、派生类对象调用测试说明

Q:派生类能否调用基类的函数?

A:可以并且如果重定义的话可以直接调用不用加作用域,如果重定义的话需要加using或者作用域 

解析:派生类对象在调用函数时,会从派生类类中查找是否有该函数,发现没有后进一步查找基类

Q:为什么重定义hello()函数后不能直接调用基类的hello(std::string str)

A:   基类有很多重载函数,而派生类重写了基类的函数,那么默认情况下,基类中的这些所有的重载函数都不可以使用了。参考hello函数

如果我们希望只覆盖基类中的一部分函数,而其他函数在派生类中还没有被覆盖,一种使用方法就是使用using声明。这样的话就无须覆盖基类中的每一个重载版本了
using声明只需要给出名称,而不需要给出参数列表,因此基类中的所有重载函数在派生类中都可以使用了
注意:使用using声明时,当using在派生类的不同的访问模式(public、protected、private)下,那么基类的函数在派生类中就属于该访问模式

二、基类指针指向派生类对象说明

派生类对象可以赋值给基类的对象/基类的指针/基类的引用。有一种很形象的说法叫做切片或者切割。就是把派生类当中父类的那部分切来赋值过去。

用基类指针绑定的子类对象,只能通过这个基类指针调用基类中的成员,因为作用域仅限于基类的子对象,子类新增的部分是看不见的

类继承关系梳理_第2张图片

Q:因为是切片所以如果基类和派生类同时拥有一个同名变量时候基类指针会使用基类变量/函数

A:对

Q:为什么虚函数会使用派生类

A:因为虚函数是通过虚函数表实现原理可以参考下:C++中继承及virtual小结_c++ virtual 继承-CSDN博客

三、参考文献

C++:91---类继承(继承中类的作用域(附加:隐藏、重写(覆盖)))_mb6128aabee41d4的技术博客_51CTO博客

C++中的继承/虚继承原理-CSDN博客

你可能感兴趣的:(c#,开发语言)