[C++基础]继承


继承

因为本科的时候接触过一段时间java,对继承这个概念印象深刻。

继承限定词

public:父类怎样子类就怎样

class CChild: public CPeaple
{ 
};

protected:继承之后,父类的public降级成protected,父类中的protected和private不变
父类中的属性不会改变

class CChild: protected CPeaple
 {
 };

private:继承之后,父类中都降级成private

class CChild: private CPeaple
{
};

成员的继承

无参构造函数:

继承构造的调用顺序:先父类再子类;

含参构造函数

如果父类有构造函数,且有参数,子类的构造函数一定要写出来。参数在参数列表传递

class CFather
{
public:    
    CFather(int a);
    {

    }
}
class CSon:public CFather
{
public:
    int a;
    CSon():CFather(1);
    {

    }
};

参数传递只能两级之间。如果CFather继承了别的类,只需在CFather类中加入参数列表,和CSon没关系。

当有多个构造函数时,根据参数列表的个数决定调用哪个构造函数

析构函数

析构函数调用顺序:先子类再父类

覆盖

在子类中有和父类中同名的数据成员,把父类中的覆盖,如果想在子类中用父类的数据成员:
类内:

cout<<CFather::a<<end;

类外:

CSon so;
cout<<so.CFather::a<<endl;

子类函数和父类函数同名,并不是重载,调用的时候必须使用CFather::来调用父类的函数。

友元函数不能被继承

多态和虚函数

多态只针对指针对象,虚函数只针对于函数成员;

父类的指针调用子类的函数

CFather *fa = new CSon;
fa->show()//普通函数只能调用父类自己的成员

虚函数virtual:

//父类:

virtual void show()//虚函数
{
 cout<<"father"<<endl
}

//子类:
void show()
{
 cout<<"son"<<endl
}

//main:
CFather *fa = new CSon;
fa->show()//用父类的指针调用子类的成员

只有函数名字一样,才能达到这个虚函数调用效果。

重写

针对虚函数;

1.父类是虚函数,子类重写的函数,默认是虚函数;

返回值类型必须相同

2.特殊情况(协变):

当返回的是当前类的引用或者指针,返回值的类型可以是各自类类型。

3.虚函数不能是内联函数

4.构造函数不能是虚函数

虚表

CFather* fa=new CSon;
fa->show;
*(int*)fa//获得的是虚表的首地址

把对象的首地址转成int (四字节) ,然后取对象首地址的地址
avatar

*(int*)*(int*)fa//获得的是虚表的第一个的地址内容(fun)
*((int*)*(int*)fa+1)//获得的是续表第二个的地址内容(show)

虚表的首地址并不知道是什么类型,所以要先转换成int*,然后递增
代码实现:

typedef void (*p)();
((p)(*(int*)*(int*)fa+0)))()//调用 取内容 fun

虚析构

多态中,如果释放父类指针,只会调用父类的析构函数,变成虚析构后,子类父类都调用