八十一. 类的继承方式
#include <iostream>
using namespace std;
//规则1,只要是父类中的private成员,不管是什么继承方式,儿子都访问不了
//规则2,如果是公有(public)继承,儿子中的访问控制权限保持不变
//规则3,如果是保护(protected)继承,除了父亲中的private成员,在儿子中,都是protected成员
//规则4:如果是私有(private)继承,儿子中的父亲除了private成员,其余在儿子中,也都是private成员
class Parent
{
public:
int pub = 1;// 在类的内部和外部都能访问
protected:
int pro = 2; //在类的内部可以访问,在类的外部不可以访问
private:
int pri = 3;//在类的内部可以访问,在类的外部不可以访问
};
//公有继承
class Child: public Parent
{
public:
void func()
{
cout<<pub<<endl;// pub 是父类的public成员变量,在public继承类的内部可以访问,外部也可以
cout<<pro<<endl; //pro 是父类的protected成员变量,在public继承类的内部可以访问,而外部不能
//此时的pro在孙子类中能够访问,说明此时pro不是private成员,是protected成员
//cout<<pri<<endl; //pro 是父类的private成员变量,在public继承类的内部和外部都不能访问
}
};
//孙子类
class SubChild : public Child
{
public:
void func2()
{
cout<<pro<<endl;
}
};
//保护继承
class Child2: protected Parent
{
public:
void fun2(){
cout<<pub<<endl; //此时pub通过protected继承,能够在类的内部访问
//pub在类的内部可以访问,类的外部访问不了,类的儿子可以访问
//pub就是protected成员
}
};
class SubChild2 :public Child2
{
public:
void sub_func2(){
cout<<pub<<endl;
}
};
//私有继承
class Child3: private Parent
{
public:
void func3()
{
cout<<pub<<endl;//pub在类的内部可以访问,在类的外部不能访问
//pub在儿子中访问不了,说明PUB在Child3中是私有成员
cout<<pro<<endl;//pro在儿子中访问不了,说明PUB在Child3中是私有成员
}
};
class Sub_Child3: public Child3
{
public:
void sub_fun3()
{
//cout<<pub<<endl;
//cout<<pro<<endl;
}
};
//三看原则:
//1 看调用的成员变量,是在类的内部还是类的外部
//2 看儿子的继承方式
//3 看当前变量在儿子中的变量,在父亲中的访问控制权限。
int main()
{
Child c1;
c1.func();
c1.pub;
//c1.pro; //pro 是父类的protected成员变量,在public继承类的内部的外部不能访问
cout<<"------------"<<endl;
SubChild s1;
s1.func2();
cout<<"------------"<<endl;
SubChild2 s2;
s2.sub_func2();
//s2.pub;
return 0;
}
八十二. 类的继承方式练习
#include <iostream>
using namespace std;
class A
{
private:
int a;
protected:
int b;
public:
int c;
A()
{
a = 0;
b = 0;
c = 0;
}
void set(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
}
};
class B: public A
{
public:
void print()
{
//cout<<"a= "<<a;//a是父类的私有成员,访问不了
cout<<"b= "<<b;//b是保护成员,类的内部可以访问
cout<<"c= "<<c;//c是公有成员,类的内部可以访问
}
};
class C: protected A
{
public:
void print()
{
//cout<<"a= "<<a;//a是父类的私有成员,访问不了
cout<<"b= "<<b;//b在子类中是保护成员,类的内部可以访问
cout<<"c= "<<c;//c是公有成员,类的内部可以访问
}
};
class D: private A
{
public:
void print()
{
//cout<<"a= "<<a;//a是父类的私有成员,访问不了
cout<<"b= "<<b;//b此时是private成员,类的内部可以访问
cout<<"c= "<<c;//c此时是private成员,类的内部可以访问
}
};
int main()
{
A aa;
B bb;
C cc;
D dd;
aa.c = 100;// c是公有,类的外部可以访问
bb.c = 100;// B public 继承于A,保持权限不变,c是公有,类的外部可以访问
//cc.c = 100;// C protected 继承于 A, c在此类中是protected成员,类的外部不能访问
//dd.c = 100;// D private 继承于 A, c在此类中private成员,类的外部不能访问
aa.set(1,2,3);
bb.set(10,20,30);
//cc.set(30,40,50); //C protected 继承于 A, c在此类中是protected成员,类的外部不能访问
//dd.set(100,200,300);// D private 继承于 A, c在此类中private成员,类的外部不能访问
bb.print(); //print()是定义在B类public成员函数,在类的外部可以访问
cc.print();//print()是定义在C类public成员函数,在类的外部可以访问
dd.print(); //print()是定义在D类public成员函数,在类的外部可以访问
cout << "Hello world!" << endl;
return 0;
}
八十三. 类的赋值兼容原则
#include <iostream>
using namespace std;
class Parent
{
public:
void printP(){
cout<<"a: "<<this->a<<endl;
}
int a;
};
class Child: public Parent
{
public:
void printC()
{
cout<<"b: "<<this->b<<endl;
}
int b;
};
void myPrint(Parent *pp)
{
pp->printP();
}
int main()
{
//Parent p;
//Child c = p;//p对象填充不满c对象的空间,所以不能这样赋值。
//Child c;
//Parent p =c;//c对象所占用的内存空间,不小于p对象占用的内存空间。
//换言之,能够填充满p对象所需的空间
//c.printP();//c能够当作父类p来使用
Parent * pp = NULL;//父类指针
Child * cp = NULL;//子类指针
Parent p;//父类对象
Child c; //子类对象
//cp = &p; //这里是错误的,不能将Parent的类型,分给Child型的指针
pp = &c; //这里是可以的的,可以将Child的类型,分给Parent型的指针
//这里是因为,c的内存布局能够满足父类指针的全部需求,可以用一个儿子的对象地址给父类指针赋值
//cp->printC();
pp->printP();
//上述方法的意义在于,通过一个myPrint()就可以实现,对父类和子类的调用
pp = &p;
cp = &c;
myPrint(pp);
myPrint(cp);
return 0;
}
八十四. 子类中的构造和析构
#include <iostream>
using namespace std;
class Parent
{
public:
Parent()
{
cout<<"Parent()..."<<endl;
a = 0;
}
Parent(int a)
{
cout<<"Parent(int a)..."<<endl;
}
~Parent()
{
cout<<"~Parent()..."<<endl;
}
int a;
};
class Child: public Parent
{
public:
//在调用子类的时候,一定调用父类的构造函数
//父类先构造,子类后构造
Child(int a, int b):Parent(a)
{
cout<<"Child(int a, int b)..."<<endl;
this->b = b;
}
void printC()
{
cout<<"b= "<<b<<endl;
}
~Child()
{
cout<<"~Child()..."<<endl;
}
int a;
int b;
};
int main()
{
Child c(10,20);
c.printC();
return 0;
}