每个类控制着成员对于派生类来说是否是可以访问的.需要注意procted的成员只对于派生类对象本身可以访问,但是派生类的成员函数和友元对于一个基类成员的procted成员没有访问特权.
class Sneak:public Base
{
friend void clobber(Base&);
}
公有,私有和受保护继承.
派生列表中的访问说明符对于派生类成员能否访问其基类的成员没有影响,它影响的是派生类用户以及派生类的派生类对这些成员的访问权利.
派生类向基类的转换的可访问性
对于代码中某个节点,如果基类的公有成员可访问,则派生类向基类的访问是可以的,反之则不行.
[练习]:定义一个图形的类体系.
#include "iostream"
#include "string"
#include "iterator"
#include "vector"
#include "algorithm"
#include "numeric"
#include "functional"
using namespace std;
#define PI 3.14159265358979323846
class shape
{
public:
shape() = default;
/************** 构造函数******************/
shape(const string&s) :
name(s){}
/**************定义纯虚函数,返回面积和周长******************/
virtual double area()const = 0;
virtual double perimeter()const = 0;
virtual ~shape(){}
private:
string name;
};
/********定义多边型类***************/
class polygon : public shape
{
public:
polygon() = default;
/************定义构造函数***********************/
polygon(const string& s,const vector<double>& vec) :shape(s),side(vec), n(vec.size()){}
/***********接受列表形式的构造函数*************/
polygon(const string& s,initializer_list<double> il) :shape(s) ,n(il.size()){
copy(il.begin(), il.end(), back_inserter(side));
}
/************析构函数********************/
virtual ~polygon() = default;
double area()const override = 0;
double perimeter()const override = 0;
protected:
vector<double> side;
size_t n;
};
/****************从多边形继承长方形*********************************/
class Rectangle : public polygon
{
public:
/************定义派生类自己的构造函数************************/
Rectangle() = default;
Rectangle(const string&s, vector<double>vec) :
polygon(s,vec){}
Rectangle(const string&s, initializer_list<double>il) :
polygon(s, il){}
/**********析构函数**********************/
~Rectangle() = default;
/************覆盖抽象基类的纯虚函数area()********************/
double area()const override { return commpute_area(); }
/***************覆盖抽象基类的纯虚函数perimeter*****************/
double perimeter()const override{ return accumulate(side.begin(),side.end(),0.0); }
private:
/*********用来计算面积的函数**************************/
double commpute_area()const;
};
/*************计算面积**********************/
double Rectangle::commpute_area()const
{
return side[0] * (side[0] == side[1] ? side[2] : side[1]);
}
/****************从图形类继承圆*************************/
class Circle : public shape
{
public:
Circle() = default;
Circle(const string& s, double r) :shape(s), radius(r){}
/****************覆盖面积和周长函数*************************/
double area()const override{ return PI*radius*radius; }
double perimeter()const override{ return 2 * PI*radius; }
private:
double radius;
};
int main()
{
Rectangle re("pyb", { 3, 2, 3, 2 });
Circle c("aa", 10);
cout<<c.area();
cout << endl;
cout << re.area();
}