1.继承
继承的实质就是父类的数据子类成员中有一份
继承方式只会增强父类在子类中的权限显示
任何方式的继承子类都不能直接访问父类的私有属性,但可以通过父类留下的公有接口访问数据
#include#include using namespace std; class Fox { public: Fox(string name,int money):name(name),money(money) {}//构造函数 int& retunmoney() { return this->money; } void print() { cout << name << money << endl; } protected: string name; private: int money; }; class Son :public Fox //公有继承 { public: void print() { //cout << money << name << endl;//错误写法 任何继承子类都无法通过自身权限访问父类的私有属性 cout < 1.2 关于继承的权限问题:任何继承方式都不可以访问父类的私有属性
继承后属性提升问题 protected继承protectedprotected不可直接访问 public继承publicprotected不可直接访问 private继承privateprivate不可直接访问 知识点:当子类用私有继承父类属性后 会导致父类中的保护属性变成子类的私有属性
子类是可以访问该私有属性,但是通过子类再次继承子类之后(我们称为孙子类)
会导致孙子类无法访问任何一个属性
#include#include using namespace std; class Fox { public: Fox(string name,int money):name(name),money(money) {}//构造函数 int& retunmoney() { return this->money; } void print() { cout << name << money << endl; } protected: string name; private: int money; }; class Son :public Fox //公有继承 { public: void print() { //cout << money << name << endl;//错误写法 任何继承子类都无法通过自身权限访问父类的私有属性 cout < 2.继承中构造函数的写法
父类的数据必须由父类的构造函数初始化
子类中构造函数,必须调用父类自己的构造函数,并且使用参数列表的方式(这里指的是构造父类的情况),自己的属性初始化随便写
单继承和多继承
单继承:只有一个父类
多继承:两个或以上的父类
单继承
#include#include using namespace std; class Fox { public: Fox(string name,int money):Fname(name),money(money) {}//构造函数 int& retunmoney() { return this->money; } void print() { cout << Fname << money << endl; } protected: string Fname; private: int money; }; class Son :public Fox //公有继承 { public: void print() { //cout << money << name << endl;//错误写法 任何继承子类都无法通过自身权限访问父类的私有属性 cout < Sname = Sname; this->sonmoney = sonmoeny; } protected: string Sname; private: int sonmoney; }; class Son1:protected Fox //保护继承 { public: Son1(string Fname,int money,string Sname,int sonmoeny) :Fox(Fname, money) //利用参数初始化列表初始化父类构造函数 { //子类初始话方式随便 this->Sname = Sname; this->sonmoney = sonmoeny; } void print() { //cout << money << name << endl;//错误写法 任何继承子类都无法通过自身权限访问父类的私有属性 //cout << Fname << endl; //cout << Fox::retunmoney() << endl;//可以通过父类留下的公有接口访问父类的私有属性 cout << Sname << sonmoney << endl; cout << Fname << Fox::retunmoney() << endl; } protected: string Sname; private: int sonmoney; }; class Son2:private Fox //私有继承 { public: void print() { //cout << money << name << endl;//错误写法 任何继承子类都无法通过自身权限访问父类的私有属性 cout << Fname << endl; } protected: }; class Grandson :public Son2 //继承私有继承的子类 { void print() { // cout << name << endl;//上一个子类中所有属性都为保护属性,当前类无法访问任何一个数据 } }; int main() { Son1 Foxson("狐狸",18,"狐狸儿子",0); Foxson.print(); return 0; } 多继承:
#include#include using namespace std; class FoxM { public: FoxM(string name, int age) :Mname(name), Mage(age) {} protected: string Mname; int Mage; }; class FoxF { public: FoxF(string name, int age) :Fname(name), Fage(age) {} protected: string Fname; int Fage; }; class FoxSon :public FoxM, public FoxF //多继承 { public: FoxSon(string Mname, int Mage, string Fname, int Fage) :FoxF(Mname, Mage), FoxM( Fname,Fage)//初始化参数列表 { this->SonName = "小狐狸"; this->Sonage = 18; } void pring() { cout << Mname << Mage << endl; cout << Fname << Fage << endl; cout << SonName << Sonage << endl; } protected: string SonName; int Sonage; }; int main() { FoxSon fox1("母狐狸",15,"大狐狸",12); fox1.pring(); return 0; } 3.关于继承中同名的问题
数据成员同名
成员函数名同名
正常赋值调用
#include#include using namespace std; class Fox1 { public: Fox1(string name,int age):name(name),age(age) {} void printf() { cout << name << age< name = "狐狸"; this->age = 3; } void printf() { cout << name << age << endl;//就近原则 在继承中 出现同名行为或者数据 都是就近原则 Fox1::printf();//可以使用类名限定的方式去访问 cout << Fox1::name << Fox1::age << endl;//可以使用类名限定的方式去访问 } protected: string name; int age; }; int main() { Fox2* pFox2 =new Fox2("狐狸123",5); pFox2->printf();//优先调用自己子类中的同名函数 pFox2->Fox1::printf();//通过类名限定调用父类中的同名函数 return 0; } 非正常赋值调用
允许子类对象填充父类指针
int main() { //非正常调用 Fox1* PFox1 = new Fox2("狐狸",3); PFox1->printf();//优先调用指针类型的函数,也就是调用父类中的成员函数 return 0; }菱形构造的问题
所谓菱形构造问题就是 一个父类产生单独的两个子类,都继承了父类的数据成员
当两个子类又再次多继承出来一个子类 会导致构造函数中出现相同的数据成员
virtual关键字避免了该情况的发生,用virtual修饰子类,出现菱形继承时,默认使用最构造父类的构造函数初始父类中的数据成员,有效的避免了产生相同的数据成员问题
#include#include using namespace std; //继承的属性一致都存在 class A { public: A(int a) :a(a) {} protected: int a; }; class B :virtual public A { public: B(int a, int b) :A(a), b(b) {} protected: int b; }; class C :virtual public A { public: C(int a, int c) :A(a), c(c) {} void printC() { cout << a << endl; } protected: int c; }; class D :public C, public B { public: //菱形继承,必须调用祖父的构造函数 D() :B(100, 200), C(300, 400), A(1011) { } void printf1()//A为1011 使用最开始父类的值 { //只有一个a 只有一份 cout << a << endl; cout << B::a << endl; cout << C::a << endl; printC(); } protected: }; 析构问题
构造顺序和参数初始化列表的顺序无关,构造顺序和继承顺序一致
析构是反过来的
#include#include #include using namespace std; class A { public: A() { cout << "A"; } ~A() { cout << "A"; } protected: }; class B :public A { public: B() { cout << "B"; } ~B() { cout << "B"; } }; class C { public: C() { cout << "C"; } ~C() { cout << "C"; } }; class D { public: D() { cout << "D"; } ~D() { cout << "D"; } }; //构造顺序和继承顺序一致 class F :public C, public A, public D { public: //任何构造顺序问题,都和初始化参数列表无关 F() { cout << "F"; } ~F() { cout << "F"; } }; int main() { { B b; //ABBA } cout << endl; F f;//C A D F F D A C // return 0; } 作业:
实现形状类的继承
#include#include using namespace std; class Shape { public:Shape(string form="",double length = 0.0, double breadth = 0.0, double radius = 0.0) {}//缺省方式 protected: double length;//长度 double breadth;//宽度 double radius;//半径 string form;//形状 }; class Rect :public Shape { public: Rect(string form, double radius, double breadth=0.0, double length=0.0) :Shape(form, length, breadth, radius) { this->perimeter = radius * 2 * 3.14; this->area = 3.14 * radius * radius; } void printf() { cout << "形状是" << "t" << Shape::form << "面积是" << area << "周长是" << perimeter; } private: double perimeter; double area; }; class Circle :public Shape { public: Circle(string form, double radius=0.0, double breadth = 0.0, double length = 0.0) :Shape(form, radius, breadth, length) { this->perimeter = (breadth + length) * 2; this->area = breadth * length; } void printf() { cout << "形状是" << "t" << Shape::form << "面积是" << area << "周长是" << perimeter; } private: double perimeter; double area; }; int main() { Rect testpact("圆形", 5); testpact.printf(); Circle testcircle("长方形",0.0,5,10); testcircle.printf(); return 0; } 作业2:多名老师为父类的研究生类:
#include#include using namespace std; class Teacher { public:Teacher(string name):Tname(name) { } protected: string Tname; }; class Student { public:Student(string Sname) :Sname(Sname) {} protected: string Sname; }; class Graduate:public Teacher, Student//继承老师类和学生类 { public: Graduate(string Sname, string Tname) :Teacher(Tname), Student(Sname) {} void printf() { cout << "该研究生名:" << Sname << "t" << "老师名" << Tname << endl; } protected: }; int main() { Graduate fox("小狐狸", "莫大帅"); fox.printf(); return 0; } 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)