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

}

注:友元函数与类无是一个普通函数,所以友元函数不会继承。

C++语言笔记系列之十四——继承后的访问权限

时间: 2024-10-03 13:48:23

C++语言笔记系列之十四——继承后的访问权限的相关文章

C++语言笔记系列之十二——C++的继承

C++的继承 1.继承方式 public(公有继承) 派生类中的成员可以访问基类的public成员和protected成员,但不能访问基类的private成员. 派生类的对象只能访问基类的public成员. protected(保护继承),private(私有继承) 派生类中的成员可以访问基类的public成员和protected成员,但不能访问基类的private成员. 派生类的对象不能访问基类的任何成员. 2.例子 example 1: #include <iostream.h> clas

C++语言笔记系列之十六——赋值兼容规则&amp;多继承的二义性

1.赋值兼容规则 (1)派生类对象可以给基类对象赋值,这种情况下派生类对象将从基类继承的成员的值赋值给一个基类对象:但是不允许将一个基类的对象赋值给一个派生类. (2)可以将派生类对象的地址赋给基类指针,使基类指针指向派生类对象,通过基类指针引用成员时只可以引用派生类从基类继承而来的成员,而不允许引用派生类的新成员. (3)引用与指针相同. 2.多继承 (1)一个派生类从两个以上的基类中去继承. (2)说明: class 派生类名:继承方式 基类1, 继承方式 基类2,...... {派生类成员

C++语言笔记系列之十八——虚函数(1)

1.C++中的多态 (1)多态性:同一个函数的调用可以进行不同的操作,函数重载是实现多态的一种手段. (2)联编:在编译阶段进行联接,即是在编译阶段将一个函数的调用点和函数的定义点联接起来. A.静态联编:在编译阶段就完成的函数联编--函数重载. B.动态联编:在程序的运行阶段由系统自动选择具体的函数--虚函数. 注:C++的多态主要指的就是动态联编. 2.虚函数 (1)虚函数是在函数的定义时将其声明为虚函数即可. (2)说明:virtual 数据类型 函数名(参数表) {函数体} A.目的:当

C++语言笔记系列之十五——派生类、基类、子对象的构造和析构函数调用关系

例子 example 1 注:若一个基类同时派生出两个派生类,即两个派生类从同一个基类继承,那么系统将为每一个简历副本,每个派生类独立地使用自己的基类副本(比如基类中有属于自己类的静态变量等). #include <iostream.h> class Person { public: person() {cout<<"Construction of person."<<endl;} ~person() {cout<<"Destr

C++语言笔记系列之十九——虚函数(2)

1.构造函数和析构函数中调用虚函数 (1)采用静态编译. (2)在编译阶段自动联接自己类中的函数或基类中的函数,不在派生类中重定义一个函数. 注:构造函数和析构函数中调用的虚函数,派生类都不一定存在的情况下,只能去调用基类或者自身的函数. example 1 #include <iostream.h> class A { public: A() {} virtual void func() {cout<<"A construction."<<endl

C++语言笔记系列之十——静态成员

1.静态成员 (1)由关键字static修饰 静态变量定义语句在编译阶段就执行,运行过程中不再执行. (2)分类:静态数据成员.静态成员函数. (3)静态成员时类的所有对象共享的成员,而不是某一个对象的成员. 2.静态成员的使用 (1)在定义说明前加上static关键字.例如: static int x: (2)静态数据成员必须进行初始化,并且初始化必须在类外完成. (3)静态数据成员的初始化 数据类型 类名::静态数据成员名 = 值://注意这里没有static出现 (4)绝对不能使用对象名来

C语言例题系列--------第十四天

//27.有一个整型二维数组,大小为m x n,要求找出其中最大值所在的行和列以及该最大值. //请编写一个函数max,要求如下: //(1)以数组名和数组大小为该函数的形参 //(2)数组元素的值在main函数中输入,结果在函数max中输出  /*#include<stdio.h> int max(int x[3][4],int m,int n) { int max=x[0][0]; int i,j; for(i=0;i<m;i++) for(j=1;j<n;j++) if(ma

quick-cocos2d-x 学习系列之十四 测试用例

quick-cocos2d-x 学习系列之十四 测试用例 定义变量,创建13个场景名字 local items = { "framework.helper", "framework.native", "framework.display", "framework.crypto", "framework.network", "framework.luabinding", "fra

C++语言笔记系列之十七——虚基类

1.虚基类 考虑这样一种情况:当某个类的部分或者全部直接基类是另一个共同基类派生而来,这些直接基类从上一级基类继承而来的成员就一定拥有相同的名称,这样就会产生二义性问题. 解决办法:当派生类和直接基类产生了二义性问题-->加类的作用域. 当派生类和间接基类产生了二义性问题-->虚基类. 2.虚基类的说明: class 派生类名:virtual 访问权限 基类名 {派生类定义}; 注意:在定义派生类时将需要继承的基类进行虚化声明,虚基类的说明在派生类的定义中完成. 作用:将基类说明为虚基类之后,