类的继承
目的:为了提高代码的复用性(偷懒)
相关名词:父类、子类(这俩一对儿)、基类、派生类(这俩一对儿)、Base、Derived(这俩一对儿)
一些方法:
常见继承方式:
class Derived:Base{...} //默认情况下是private的
class Derived:public Base{...} //需要改的话加个public
基类的private函数布恩那个被继承
如果是public继承了基类的public函数,那么就是派生类的public,派生类的对象可以访问。
如果是private继承了基类的public函数,那么就是派生类的private,派生类成员函数可以访问,但派生类的对象不能访问。
使用using关键字,通过
using Base::Base;
来让派生类拥有基类的相应参数的构造函数
基类某个构造函数是私有的,那么不能在派生类中声明继承这个构造函数。
函数重写
基类已经定义了的一个函数,它的派生类里面可以重新定义。就相当于是在偷懒的时候,还得改点东西,那么原来的不用了,就以“最新版”的为准就行了。【派生类里面需要重写的函数名和参数必须基类的一模一样】此时所有相关的重载函数(同名不同参的其他函数)也一概不能用了。但可以通过using ClassName::MemberFuncName的形式恢复指定成员函数。
【我竟然能直接看懂理解,我真厉害(乐.jpg)】
虚函数(?)
【向上映射与向下映射】:派生类对象转换为基类对象,叫做向上映射,反之叫向下映射。
派生类到基类的向上映射,可以由编译器自动完成,是隐式的自动类型转换。派生类里的对象
那么我现在需要解决的问题就成了:【当函数重写的时候,调用之后是用重写前,即基类里的函数?还是重写后,即派生类里的函数?】(应该是这个问题吧,应该... )
virtual关键字
virtual 返回类型 函数名(形参);
这样的虚函数,如果在基类里声明成了虚函数,那么派生类重写后,它就一直都是虚函数。
虚函数主要实现的就是【多态性】。程序会根据对象实际类型来确定调用哪个函数。
我让C知道给出一个例子:
#include <iostream>
class Animal {
public:
virtual void makeSound() {
std::cout << "Animal makes a sound." << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
std::cout << "Dog barks." << std::endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
std::cout << "Cat meows." << std::endl;
}
};
int main() {
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->makeSound(); // Output: Dog barks.
animal2->makeSound(); // Output: Cat meows.
delete animal1;
delete animal2;
return 0;
}
感觉上面的例子就像一个树形结构,然后基类是根节点,通过这个根节点和具体派生对象的使用,来决定具体调用哪个函数。
感觉virtual打通了从基类到派生类的路子。
也就是如果定义了一个派生类的对象,但一个函数的参数是基类规定的对象的引用,这时候,我如果拿派生类的对象作为这个函数的参数,这个函数就会自己找派生类里面符合条件的响应函数。
void fun(Base& obj){obj.print()} //print是基类派生类都有的(虚)函数
int main()
{
Derive d; //定义派生类对象d
d.print(); //这时候调用的是派生类里面的print函数
fun(d); //这时候调用的还是派生类里的print函数
return 0;
}
类似于上面的,感觉析构的时候也需要加上virtual
final关键字
使用final来修饰基类虚函数(派生类 相对于 派生类的派生类,也相当于 基类),这个基类的派生类不可再重写。
class A{
public:
virtual void func() = 0;
};
class B : public A {
public:
void fun() final;
};
如果再给class B搞个派生类class C,C就没办法重写fun()。
纯虚函数
就是再基类声明的虚函数,【没有具体实现】,仅提供接口,定义派生类必须各自实现的方法。通过:
virtual 返回类型 FuncName(参数) = 0
来标识。
【要过年啦!!!啊啊啊!!!兴奋,起飞~感谢老婆一直以来的支持和肯定。听到老婆说我真的切切实实努力了改变了,瞬间充满了力量😄😄😄】