程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++語言筆記系列之十四——繼承後的訪問權限

C++語言筆記系列之十四——繼承後的訪問權限

編輯:C++入門知識

1.析構函數不繼承;派生類對象在析構時,基類析構函數的調用順序與構造函數相反。
注:派生類對象建立時要調用基類構造函數,派生類對象刪除時要調用基類析構,順序與構造函數嚴格相反。
2.例子
example 1

#include
#include

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< cout< cout< }
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):("< }
注:無論該題目的繼承方式為public還是protected,調用的Rect.move都是派生類中的move函數(優先派生類)。調用順序是:
基類-->基類;派生類-->派生類(若無)-->基類。
3.繼承的支配規則
基類無法訪問派生類的成員。派生類對象或成員也可以引用基類同名成員,這時候需要加上基類的類名作用域。
派生類對象調用:派生類對象.基類名::成員函數()
派生類成員調用:基類名::成員函數
4.例子
example 1

#include
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
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
}
注:友元函數與類無是一個普通函數,所以友元函數不會繼承。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved