惠州市惠城区建设局网站,外贸网址,app应用网站单页模板,湖南企业竞价优化首选概念
假设基于A类#xff0c;创建了B类#xff0c;那么称A为B的父类#xff0c;B为A的子类
子类会继承父类的成员变量及成员函数#xff0c;但是不能继承构造、析构、运算符重载
假设又基于B创建了C#xff0c;那么称B为C的直接基类#xff0c;A为C的间接基类
继承按…概念
假设基于A类创建了B类那么称A为B的父类B为A的子类
子类会继承父类的成员变量及成员函数但是不能继承构造、析构、运算符重载
假设又基于B创建了C那么称B为C的直接基类A为C的间接基类
继承按照字面意思就是继承而不是包含当然了在代码中如果两个类只包含关系也可以这么写但是不建议。比如人继承了生物人包含了生物的属性和方法同样人包含了脑袋但是不建议说人继承了脑袋。同样一粒米属于米类即使一粒米长了翅膀它也是米的一种它是由米演变而来的它继承了米的所有属性及方法也演变了自己的属性和方法。
语法
class A
{
public:int time;
}
class B:public A
{
public:int x;int y;
}
class C:public B
{int hp;
}
这里B继承了AC继承了BC包括了A和B的所有成员属性及函数B只包括了 A的属性及函数
这里如果继承语法里面的public不写不写就相当于private
protected使用时机
当继承父类时父类的private成员不能被子类访问但是父类的private成员在子类的内存中还是存在只是不能访问而protected属性和private没有区别唯一区别是在继承后它的子类可以访问父类的protected成员
final关键字
当加上关键字后这个类就不能被继承
public、protected等继承的区别
继承方式为public,则父类中的public成员被继承为public,protected被继承为protected,父类中的private被继承不可访问
继承方式为protected,则父类中的pulic成员被继承为protectedprotected被继承为protectedprivate被继承不可以访问
继承方式为private父类中的public和protected被继承为privateprivate成员被继承不可访问
如果我们想要修改子类继承父类的成员权限时可以用using 父类::成员
class A
{
protected:int x;int y;
};
class B :public A
{
public:using A::x;
};
int main()
{B b;b.x 100;A a;a.x 200;
}比如这样就修改了x在B中的权限但是这段代码还是不能运行因为x在A中还是以proteced的特征存在
构造函数和继承
#include iostream
class Object
{
protected:char Name[5]{};
public:Object(){std::cout Object is created std::endl;}
};
class seeObject:protected Object
{
public:int x;seeObject(){std::cout seeObject is created std::endl;}
};
int main()
{seeObject stone;system(pause);
}
这里当实例化seeobject对象 stone时会同时调用父类的构造函数因为在子类中继承了父类的成员变量所以实例化也要实现这个成员变量从而调用默认构造构造顺序是父类构造、子类构造因为在seeobject类的内存中父类的成员在前面。
#include iostream
class Object
{
protected:char Name[5]{};
public:Object(){std::cout Object is created std::endl;}Object(const Object obj){std::cout Object copy is created std::endl;}
};
class seeObject:protected Object
{
public:int x;seeObject(){std::cout seeObject is created std::endl;}seeObject(const seeObject seeobj){std::cout seeObject copy is created std::endl;}
};
class creature:protected seeObject
{
protected:int hp;
public:creature(){x 3200;std::cout creature is created std::endl;}creature(const creature cret){std::cout creature copy is created std::endl;}
};
int main()
{creature monkey;creature monkey2 monkey;system(pause);
} 这里子类进行复制构造时不会调用父类的复制构造函数子类实例化时都是调用父类的默认构造函数不会调用其他构造比如不会调用父类的复制构造除非显示指定
为什么呢
当进行复制构造的时候按理说人类拥有了动物类的所有成员变量当进行人类的对象复制构造时那这个时候会调用人类的复制构造函数动物类的复制构造会不会被调用呢如果说人类实例化对象也属于动物类的话那么动物类的复制构造也会被调用 按照语法规定不会调用动物类的复制构造只会调用动物类的构造函数 为什么会调用动物的普通构造呢直接一点直接调用人的复制构造不就好了吗直接一次性全部打包复制这是因为人的继承属性属性必须初始化而这个属性是属于动物类的就会默认调用动物的默认构造进行初始化人不会继承动物的默认构造但是会调用它 为什么不调用动物的复制构造呢就好比动物有血有肉人有血有肉动物的血肉值为100人的血肉值为200当复制人的时候肯定是复制200的血肉值所以肯定不是调用动物的复制构造不然血肉值也成了100只需要把人的继承属性调用动物的普通构造初始化再加上人的特有属性两个加起来再调用复制构造复制过去即可。 为什么不调用人的普通构造呢因为既然要复制一个人所以就肯定会调用复制构造当给人进行普通构造的时候就好比初始化一个人的血肉值为10然后实例化后将人的血肉值设置为200那么当复制这个人的时候肯定不会再调用这个人的普通构造因为这样又将他设置成了10。所以调用了复制构造肯定不会再调用普通构造 那么问题来了按照前面所说调用了动物的普通构造将血肉值初识化成了100只调用人的复制构造不调用人的普通构造那么在进行复制的时候会不会把100也给复制过去呢不会的因为在创建这个要复制的对象时已经给它进行了初始化血肉值为200就好比要复制一块金子这块金子早就已经点石成金了不用担心复制一块石头过去。 #include iostream
class seeObject
{
public:int x;seeObject(){std::cout seeObject is created std::endl;}seeObject(const seeObject seeobj){std::cout seeObject copy is created std::endl;}seeObject(int val) :x{ val }{ }
};
class creature:protected seeObject
{
protected:int hp;
public:/using seeObject::seeObject;creature():seeObject {100},hp{200}{x 3200;std::cout creature is created std::endl;}creature(const creature cret):seeObject{cret}{std::cout creature copy is created std::endl;}
};
int main()
{creature monkey;creature monkey2 monkey;system(pause);
}
这里采用成员初始化列表的方式将100传入seeObject(int val)注意这里的x3200,只能写在括号里面而不能用初始化列表的方式因为这里还未完成构造
当子类委托构造父类的复制构造函数时传入的参数是子类类型也可以因为子类实例化对象类型也属于父类对象类型比如人属于动物类,虽然子类多了自己的属性和方法但它仍然符合父类的定义 知识扩展*1.通常来说,子类肯定含有父类所有的成员变量和方法函数.所以用父类指针指向子类时,没有问题因为父类有的,子类都有,不会出现非法访问问题. 2.如果用子类指针指向父类的话,一旦访问子类特有的方法函数或者成员变量(基类是没有的),就会出现非法访问; 因为被子类指针指向的由父类创建的对象,根本没有要访问的那些内容,那些是子类特有的,只有用子类初始化对象时才会有
对于第23行using seeObject::seeObject;这句代码是继承父类的有参构造函数使用using继承构造函数是不能继承默认构造和副本构造其他都可以继承比如有参构造。继承下来的构造函数不改变它的属性如果在父类中它是public那么继承后如果把using seeObject::seeObject;这段代码放入creature的private中它也是public属性。
继承构造时不能选择继承哪个有参构造而是将所有有参构造全部继承下来
继承和析构
析构的顺序和构造相反最先析构的是子类然后才是父类因为子类对父类有依赖所以要先析构子类。当把子类中的原有成员销毁时调用子类的析构然后销毁继承的成员时又会调用父类的析构