Part 1 知识点
1)基本知识点
在C++中,派生类的一般定义语法为:
class 派生类名:继承方式 基类名1,继承方式 基类名2,继承方式 基类名3,……,继承方式 基类名n
{
派生类成员声明;
};
其中继承方式规定了如何访问从基类继承的成员。继承方式关键字为:public,private和protected,分别表示公用继承,私有继承和保护继承。如果不显式地给出继承方式关键字,系统地默认值就认为是私有继承。
2)重要知识点
认真翻阅了继承这一章,我认为重要的知识点主要集中在访问控制上,下面通过实验来进行检验。
Part 2 实验
公有继承,私有继承,保护继承的区别:
公有继承:
#ifndef Point_h
#define Point_h
class Point {
public:
void initPoint (float x=0,float y=0){this->x =x ;this->y=y;}
void move(float offX,float offY) {x+=offX; y+=offY;}
float getX() const{return x;}
float getY() const{return y;}
private:
float x,y;
};
#endif /* Point_h */
#ifndef Rectangle_h
#define Rectangle_h
#include "Point.h"
class Rectangle:public Point {
public:
void initRectangle(float x,float y,float w,float h){
initPoint(x,y);
this->w=w;
this->h=h;
}
float getH()const {return h;}
float getW()const {return w;}
private:
float w,h;
};
#endif /* Rectangle_h */
#include <iostream>
#include <cmath>
#include "Rectangle.h"
using namespace std;
int main(){
Rectangle rect;
rect.initRectangle(2, 3, 20, 10);
rect.move(3, 2);
cout<<"The data of rect(x,y,w,h): "<<endl;
cout<<rect.getX()<<","
<<rect.getY()<<","
<<rect.getW()<<","
<<rect.getH()<<","<<endl;
return 0;
}
输出结果:
私有继承和保护继承在直接继承中的结果是一样的:
#ifndef Point_h
#define Point_h
class Point {
public:
void initPoint (float x=0,float y=0){this->x =x ;this->y=y;}
void move(float offX,float offY) {x+=offX; y+=offY;}
float getX() const{return x;}
float getY() const{return y;}
private:
float x,y;
};
#endif /* Point_h */
#ifndef Rectangle_h
#define Rectangle_h
#include "Point.h"
class Rectangle:protected Point { //这里用private来控制继承方式结果完全相同
public:
void initRectangle(float x,float y,float w,float h){
initPoint(x,y);
this->w=w;
this->h=h;
}
float getH()const {return h;}
float getW()const {return w;}
//下面是新增代码
void move(float offX,float offY){Point::move(offX,offY);}
float getX() const {return Point::getX();}
float getY() const {return Point::getY();}
private:
float w,h;
};
#endif /* Rectangle_h */
#include <iostream>
#include <cmath>
#include "Rectangle.h"
using namespace std;
int main(){
Rectangle rect;
rect.initRectangle(2, 3, 20, 10);
rect.move(3, 2);
cout<<"The data of rect(x,y,w,h): "<<endl;
cout<<rect.getX()<<","
<<rect.getY()<<","
<<rect.getW()<<","
<<rect.getH()<<","<<endl;
return 0;
}
输出结果与上面完全一样。
尽管私有继承与保护继承在直接派生中的结果相同,但在间接派生中是有区别的。
#ifndef square_h
#define square_h
#include "Rectangle.h"
class square:private Rectangle {
public:
void initsquare(float x,float y,float w,float h){
initPoint(x,y);
this->w=w;
this->h=h;
}
float getH()const {return h;}
float getW()const {return w;}
void move(float offX,float offY){Point::move(offX,offY);}
float getX() const {return Point::getX();}
float getY() const {return Point::getY();}
private:
int j,k;
}
#endif /* square_h */
以私有继承的方式来继承point。无论square以哪种方式继承Rectangle,想在square中直接访问Point类里的initsquare函数,都会直接报错。
而如果以保护继承的方式来继承point。square除了private的方式继承Rectangle外(public、protected),都可以在类里通过类名直接访问Point类里的initsquare函数。
Part 3 总结
通过以上实验我们可以知道如果以保护继承的方式继承基类,除了(被保护的)派生类可以访问基类以外,绝对不可能被外部使用者访问。
如果合理地利用保护成员,就可以在类的复杂层次关系中在共享与成员隐蔽之间找到一个平衡点,既能实现成员隐蔽,又能方便继承。