王老师 C++ 类的继承

1.类的继承

语法: class 导出类名 : 继承方式 基类名1, ..., 继承方式 基类名n 类体 

继承方式有public, protected, private三种.

导出类对象构成:(1)基类的对象; (2)导出类部分.

导出类中成员的访问权限,如下表所示.

继承方式基类private成员基类protected成员基类public成员
privateprivateprivateprivate
protectedprivateprotectedprotected
publicprivateprotectedpublic

测试程序:

#include "stdafx.h"
class Base
{
private:
 int b1;
protected:
 int b2;
public:
 int b3;
};

class D : public Base
{
private:
 int d1;
protected:
 int d2;
public:
 int d3;
};

class E :private D
{
private:
 int e1;
protected:
 int e2;
public:
 int e3;
};

void main()
{
 Base b;
 //error C2248: 'Base::b1' : cannot access private member declared in class 'Base'
 //b.b1 = 1;
 //error C2248: 'Base::b2' : cannot access protected member declared in class 'Base'
 //b.b2 = 2;
 b.b3 = 3;

 D d;
 //error C2248: 'Base::b1' : cannot access private member declared in class 'Base'
 //d.b1 = 1;
 //error C2248: 'Base::b2' : cannot access protected member declared in class 'Base
 //d.b2 = 2;
 d.b3 = 3;
 //error C2248: 'D::d1' : cannot access private member declared in class 'D'
 //d.d1 = 4;
 //error C2248: 'D::d2' : cannot access protected member declared in class 'D'
 //d.d2 = 5;
 d.d3 = 6;

 E e;
 //error C2248: 'Base::b1' : cannot access private member declared in class 'Base'
 //e.b1 = 1;
 //error C2248: 'Base::b2' : cannot access protected member declared in class 'Base'
 //e.b2 = 1;
 //error C2247: 'Base::b3' not accessible because 'E' uses 'private' to inherit from 'D'
 //e.b3 = 1;
 //error C2248: 'D::d1' : cannot access private member declared in class 'D'
 //e.d1 = 1;
 //error C2248: 'D::d2' : cannot access protected member declared in class 'D'
 //e.d2 = 1;
 //error C2247: 'D::d3' not accessible because 'E' uses 'private' to inherit from 'D'
 //e.d3 = 1;
 //error C2248: 'E::e1' : cannot access private member declared in class 'E'
 //e.e1 = 1;
 //error C2248: 'E::e2' : cannot access protected member declared in class 'E'
 //e.e2 = 1;
 e.e3 = 1;

}

注: 在类的外部只能访问类的public成员.

2.不可继承

(1)构造函数

(2)析构函数

(3)operator =

导出类构造函数定义:

构造函数(形参表):成员初始化表 函数体

成员初始化表: 基类名(实参表), 数据成员名(实参)

{

   普通成员赋初值;

}

构造函数调用次序:

先基类(顺序为类继承时的顺序),对象成员(顺序是在类体中声明的顺序).

析构函数调用次序正好相反.

3.虚函数

(1)向上转型

例如:

#include "stdafx.h"
class Base
{
};

class Derived : public Base
{
};

void main()
{
 Base b, *p;
 Derived d, *q;
 p = &b;

 //指向基类的指针可以指向子类,反之则不行.
 p = &d;

 q = &d;
 q = (Derived *)&b;
}

注:q = (Derived *)&b;是C语言强制转换用法,C++中应使用新引入的cast运算.

(2)绑定(binding)

由函数调用确定函数体的过程.

静态绑定:编译时绑定;

动态绑定:运行时绑定.

(3)虚函数

定义语法:

virtual 值类型 函数名(形参表) 函数体

注意:

a.在类体外定义时,virtual可不用写

b.在导出类中,override虚函数时,virtual可不写,但函数原型必须相同.

特点:使用指针或者引用调用虚函数时,具体调用哪个函数,由指针所指对象的类型决定.

例子:

#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
 virtual void f()
 {
  cout << "f in Base" << endl;
 }
 void g()
 {
  cout << "g in Base" << endl;
 }
};

class Derived : public Base
{
public:
 void f()
 {
  cout << "f in Derived" << endl;
 }
 void g()
 {
  cout << "g in Derived" << endl;
 }
};

void main()
{
 Base *p = new Derived();
 p->f();
 p->g();

 Base *q = new Base();
 q->f();
 q->g();
}

(4)纯虚函数:只声明,没有定义的虚函数

声明语法:

virtual 值类型 函数名(形参表) = 0;

抽象类:至少含有一个纯虚函数的类.抽象类不能实例化,即不能定义对象.

#include "stdafx.h"

#include <iostream>
using namespace std;

#include "string.h"

class List;

class Node
{
private:
 Node * next;

public:
 virtual void show() = 0;
 void insert(Node **h)
 {
  next = *h;
  *h = this;
 }

 friend class List;
};

class iNode : public Node
{
 int info;

public:
 iNode(int x)
 {
  info = x;
 }

 void show()
 {
  cout << info << " ";
 }
};

class sNode : public Node
{
 char s[100];

public:
 sNode(char *t)
 {
  strcpy(s, t);
 }

 void show()
 {
  cout << s << " ";
 }
};

class List
{
 Node *head;
public:
 List()
 {
  head = NULL;
 }

 void ins(Node *p)
 {
  p->insert(&head);
 }

 void display()
 {
  Node *p = head;
  while(p)
  {
   p->show();
   p = p->next;
  }
 }
};

void main()
{
 List list;

 list.ins(new iNode(1));
 list.ins(new iNode(2));
 list.ins(new iNode(3));
 list.ins(new iNode(4));
 list.ins(new iNode(5));
 list.ins(new sNode("ABC"));
 list.ins(new sNode("b"));
 list.ins(new sNode("a"));

 list.display();
}


注:虚析构函数的使用略.
 

<补充>

void insert(Node **h)
{
next = *h;
*h = this;
show();
cout << endl;
}

添加show()方法之后,首先编译不会出错,然后调用的是子类的方法.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值