一:继承访问权限
父类
class father
{
public:
string name; //姓名
protected:
string money; //财产
private:
string secret; //秘密
friend class friends;
};
1.公共继承
//1.public继承
class son_public :public father
{
public:
void test() {
name = "son_public";
money = "1/3";
secret = "none";
}
int height;
protected:
int eye;
private:
int weight;
};
2.保护继承
//2.protected继承
class son_protected :protected father
{
public:
void test() {
name = "son_protected";
money = "1/3";
secret = "none";
}
int height;
protected:
int eye;
private:
int weight;
};
3.私有继承
//3.private继承
class son_private :private father
{
public:
void test() {
name = "son_private";
money = "1/3";
secret = "none";
}
int height;
protected:
int eye;
private:
int weight;
};
修改private继承类的代码,加入using恢复访问权限(从父类继承的变量如果原本就是私有的,则无法用using改变权限)
类外访问
由上可以看出:
1.private只有自己可以访问,派生类和外部都不可以访问;protected只有自己和派生类可以访问
2.保护继承后,相当于将父类的public变量变为protected;私有继承后,相当于将父类的所有变量变为private;公共继承不改变父类变量
二、友元类继承测试
//4.友元访问
class friends
{
public:
void test(){
father f;
f.name;
f.money;
f.secret;
son_public s1;
son_protected s2;
son_private s3;
s1.name;
s1.money;
s1.secret;
s1.weight;
s1.height;
s1.eye;
s2.name;
s2.money;
s2.secret;
s2.weight;
s2.height;
s2.eye;
s3.name;
s3.money;
s3.secret;
s3.weight;
s3.height;
s3.eye;
}
};
由上可以看出:友元可以访问类的私有变量和保护变量,并且可以访问其公共继承给子类的私有变量和保护变量,但是当其继承给子类时存在保护变量的权限转变时,友元无权访问(如s2保护继承的父类变量全都不能访问,s3私有继承的父类变量中只有父类中的保护变量无法访问)
测试友元的子类,不具有从友元继承的访问权限
三、多态性综合运用
一般多态性函数
class father
{
public:
void test() {
cout << "father" << endl;
}
};
class son :public father
{
public:
void test() {
cout << "son" << endl;
}
};
int main(int argc, char *argv[])
{
father f;
f.test();
son s;
s.test();
father* ptr = new son();
ptr->test();
return 0;
}
由上可知:子类重写父类的非virtual 方法,当父类指针指向子类对象时,通过指针调用该成员函数,调用的是父类的方法(输出father)
为father的test函数添加virtual后重新测试
class father
{
public:
virtual void test() {
cout << "father" << endl;
}
};
特殊多态性函数
class father
{
public:
virtual void test() {
cout << "father" << endl;
}
};
class son :public father
{
public:
void test() {
cout << "son" << endl;
}
};
class daughter :public father
{
public:
void test() {
cout << "daughter" << endl;
}
};
void out1(father & X){
X.test();
};
void out2(father * X){
X->test();
};
int main(int argc, char *argv[])
{
father f ;
out1(f);
out2(&f);
daughter d;
out1(d);
out2(&d);
son s;
out1(s);
out2(&s);
return 0;
}
由上可知:子类可以作为父类指针的参数,并在调用时使用自身的函数而不是父类的同名函数
子类可能含有一些父类没有的成员变量或者方法函数,但是子类肯定继承了父类所有的成员变量和方法函数,父类有的,子类都有,所以不会出现非法访问问题
析构函数的多态性
class father
{
public:
virtual ~father() {
cout << "father died" << endl;
}
};
class son :public father
{
public:
~son() {
cout << "son died" << endl;
}
};
int main(int argc, char *argv[])
{
father* f = new son;
delete f;
return 0;
}
由上可知,派生类进行析构时,会自动调用基类的析构函数,从而完全释放对象
如果去掉father的析构函数virtual标识,则会只释放father并报警告
多继承
class father
{
public:
int f;
};
class son :public father
{
public:
int s;
};
class daughter :public father
{
public:
int d;
};
class grandson :public daughter,public son
{
public:
void test() {
cout << "f is"<<f << endl;
cout << "d is"<<d << endl;
cout << "s is"<<s << endl;
}
};
由上可知,类son和类daughter都有从father继承来的变量f,当它们的子类继承它们时就会出现两个f,程序不知道该调用哪一个的错误,所以需要引入虚继承
修改两个类为:
class son :virtual public father
{
public:
int s;
};
class daughter :virtual public father
{
public:
int d;
};
多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。