首页 > 代码库 > C++语言笔记系列之十四——继承后的访问权限
C++语言笔记系列之十四——继承后的访问权限
1.析构函数不继承;派生类对象在析构时,基类析构函数的调用顺序与构造函数相反。
注:派生类对象建立时要调用基类构造函数,派生类对象删除时要调用基类析构,顺序与构造函数严格相反。
2.例子
example 1
#include <iostream.h>
#include <math.h>
class Point
{
public:
Point(double a, double b, doule c)
{
x = a;
y = b;
z = c;
}
double Getx() {return x;}
double Gety() {return y;}
double Getz() {return z;}
private:
double x, y;
double z;
};
class Line:public Point
{
public:
Line(double a, double b, double c, double d):Point(a, b, c)
{k = d;}
void show()
{
cout<<Getx()<<endl;
cout<<Gety()<<endl;
cout<<Getz()<<endl;
}
private:
double k;
};
int main()
{
line obj(1.2, 3.4, 5.6, 7.8);
obj.show();
}
问题:class Line:public Point中的public可否换成protected?
答:可以,因为公有继承和保护继承,基类中的公有或者受保护成员在派生类中都可以被访问。
example 2
class Point
{
public:
Point(int i = 0, int j = 0) {x = i; y = j;}
void move(int xoff, int yoff) {x += xoff; yf += yoff;}
int Getx() {return x;}
int Gety() {return y;}
private:
int x, y;
};
class Rectangle:private Point
{
public:
Rectangle(int x, int y, int w, int h):Point(x, y)
{
W = w;
H = h;
}
void move(int xoff, int yoff)
{
Point::move(int xoff, int yoff);
}
int Getx() {return Point::Getx();}
int Gety() {return Point::Gety();}
int GetW() {return W;}
int GetH() {return H;}
private:
int W, H;
};
int main()
{
Rectangle Rect(1, 2, 3, 4);
Rect.move(5, 6);
cout<<"The data of Rect(x, y, W, H):("<<Rect.Getx()<<", "<<Rect.Gety()<<", "<<Rect.GetW()<<", "<<Rect.GetH()<<endl;
}
注:无论该题目的继承方式为public还是protected,调用的Rect.move都是派生类中的move函数(优先派生类)。调用顺序是:
基类-->基类;派生类-->派生类(若无)-->基类。
3.继承的支配规则
基类无法访问派生类的成员。派生类对象或成员也可以引用基类同名成员,这时候需要加上基类的类名作用域。
派生类对象调用:派生类对象.基类名::成员函数()
派生类成员调用:基类名::成员函数
4.例子
example 1
#include <iostream.h>
class Base
{
public:
void f1() {}
void f3() {}
};
class devived:public Base
{
public:
void f1() {}
void f2() {}
};
int main()
{
Base B1, *pb1;
devived d1, *pd1;
pb1 = &B1;
pd1 = &d1;
B1.f1(); //访问基类的f1()
pb1->f1(); //访问基类中的f1()
d1.f1(); //访问派生类中的f1()
pd1.f1(); //访问派生类中的f1()
pb1->f2(); //访问错误,没有这个成员
d1.Base::f1(); //访问基类的f1()
pd1->Base::f1(); //访问基类的f1()
d1.f3(); //访问基类中的f3()
pd1->f3(); //访问基类中的f3()
}
注:派生类对象在引用基类的同名成员时,必须加类的作用域(因为同名成员会优先派生类成员)。
在派生类f2()中访问派生类的f1():
f2() {f1()} //直接访问即可
在派生类f2()中访问基类的f1():
f2() {Base::f1()}
修改:pb1 = &d1; pb1->f1(); //访问的是基类中的f1(),因为虽然给基类的指针赋值了派生类的值,但是所指部分仍然只有派生类中继承来的基类的部分。
example 2
#include <iostream.h>
class X
{
public:
int a;
};
class Y1:public X
{};
class Y2:protected X
{};
class Y3:private X
{
private:
void f(Y1 *py1, Y2 *py2, Y3 *py3);
};
class Z:private Y2
{
private:
void f(Y1 *py1, Y2 *py2, Y3 *py3);
};
void f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N:类外不可以访问类内的受保护成员
py3->a = 7; //N:类外不可以访问类内的私有成员(私有继承过来的,类内也不可直接访问)
}
void Y3::f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N
py3->a = 7; //Y,基类中的公有a被继承为私有,类内部可以访问
}
void Z::f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N,该指针指向的是Y2,并非Z
py3->a = 7; //N
}
注:友元函数与类无是一个普通函数,所以友元函数不会继承。
注:派生类对象建立时要调用基类构造函数,派生类对象删除时要调用基类析构,顺序与构造函数严格相反。
2.例子
example 1
#include <iostream.h>
#include <math.h>
class Point
{
public:
Point(double a, double b, doule c)
{
x = a;
y = b;
z = c;
}
double Getx() {return x;}
double Gety() {return y;}
double Getz() {return z;}
private:
double x, y;
double z;
};
class Line:public Point
{
public:
Line(double a, double b, double c, double d):Point(a, b, c)
{k = d;}
void show()
{
cout<<Getx()<<endl;
cout<<Gety()<<endl;
cout<<Getz()<<endl;
}
private:
double k;
};
int main()
{
line obj(1.2, 3.4, 5.6, 7.8);
obj.show();
}
问题:class Line:public Point中的public可否换成protected?
答:可以,因为公有继承和保护继承,基类中的公有或者受保护成员在派生类中都可以被访问。
example 2
class Point
{
public:
Point(int i = 0, int j = 0) {x = i; y = j;}
void move(int xoff, int yoff) {x += xoff; yf += yoff;}
int Getx() {return x;}
int Gety() {return y;}
private:
int x, y;
};
class Rectangle:private Point
{
public:
Rectangle(int x, int y, int w, int h):Point(x, y)
{
W = w;
H = h;
}
void move(int xoff, int yoff)
{
Point::move(int xoff, int yoff);
}
int Getx() {return Point::Getx();}
int Gety() {return Point::Gety();}
int GetW() {return W;}
int GetH() {return H;}
private:
int W, H;
};
int main()
{
Rectangle Rect(1, 2, 3, 4);
Rect.move(5, 6);
cout<<"The data of Rect(x, y, W, H):("<<Rect.Getx()<<", "<<Rect.Gety()<<", "<<Rect.GetW()<<", "<<Rect.GetH()<<endl;
}
注:无论该题目的继承方式为public还是protected,调用的Rect.move都是派生类中的move函数(优先派生类)。调用顺序是:
基类-->基类;派生类-->派生类(若无)-->基类。
3.继承的支配规则
基类无法访问派生类的成员。派生类对象或成员也可以引用基类同名成员,这时候需要加上基类的类名作用域。
派生类对象调用:派生类对象.基类名::成员函数()
派生类成员调用:基类名::成员函数
4.例子
example 1
#include <iostream.h>
class Base
{
public:
void f1() {}
void f3() {}
};
class devived:public Base
{
public:
void f1() {}
void f2() {}
};
int main()
{
Base B1, *pb1;
devived d1, *pd1;
pb1 = &B1;
pd1 = &d1;
B1.f1(); //访问基类的f1()
pb1->f1(); //访问基类中的f1()
d1.f1(); //访问派生类中的f1()
pd1.f1(); //访问派生类中的f1()
pb1->f2(); //访问错误,没有这个成员
d1.Base::f1(); //访问基类的f1()
pd1->Base::f1(); //访问基类的f1()
d1.f3(); //访问基类中的f3()
pd1->f3(); //访问基类中的f3()
}
注:派生类对象在引用基类的同名成员时,必须加类的作用域(因为同名成员会优先派生类成员)。
在派生类f2()中访问派生类的f1():
f2() {f1()} //直接访问即可
在派生类f2()中访问基类的f1():
f2() {Base::f1()}
修改:pb1 = &d1; pb1->f1(); //访问的是基类中的f1(),因为虽然给基类的指针赋值了派生类的值,但是所指部分仍然只有派生类中继承来的基类的部分。
example 2
#include <iostream.h>
class X
{
public:
int a;
};
class Y1:public X
{};
class Y2:protected X
{};
class Y3:private X
{
private:
void f(Y1 *py1, Y2 *py2, Y3 *py3);
};
class Z:private Y2
{
private:
void f(Y1 *py1, Y2 *py2, Y3 *py3);
};
void f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N:类外不可以访问类内的受保护成员
py3->a = 7; //N:类外不可以访问类内的私有成员(私有继承过来的,类内也不可直接访问)
}
void Y3::f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N
py3->a = 7; //Y,基类中的公有a被继承为私有,类内部可以访问
}
void Z::f(Y1 *py1, Y2 *py2, Y3 *py3)
{
py1->a = 7; //Y
py2->a = 7; //N,该指针指向的是Y2,并非Z
py3->a = 7; //N
}
注:友元函数与类无是一个普通函数,所以友元函数不会继承。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。