继承

1.虚函数继承与非虚函数继承

如果基类是非虚函数,在继承类中重写该函数时,我想应该不属于继承,而是继承类自己定义的接口。

#include<iostream>  
#include <string>
#include <vector>
using namespace std;


class Base{
public:
	void test(){ cout << "base test" << endl; }
};

class Derived:public Base{
public:
	void test(){ cout << "derived test" << endl; }
};
int main()
{
	Base *a = new Derived();
	a->test();
	Derived b;
	b.test();
	return 0;
}
输出:

base test

derived test

如输出所示,非虚函数没有了动态绑定功能。

注意:如果不是虚函数,就不能在继承类同名函数后面加上override关键字。
因为派生类对象中含有与基类对应的组成部分(关系是is-a),所以能将派生类对象当做基类对象来使用,也能将基类的指针或引用绑定到派生类对象中的基类成分上。


2.静态成员的继承

如果基类定义了一个静态成员,则在整个继承体系中只存在该成员的唯一定义。静态成员遵循访问控制原则,如果基类的静态成员是private的,则派生类无权访问它。如果某静态成员是可访问的,则我们既可以通过基类base::staticData也可以通过继承类derived::staticData访问。


3.派生类和基类的声明

派生类的声明如下:

class Derived;               //正确
class Derived :public Base;  //错误
基类只声明不定义不能被继承:派生类包含并使用从基类继承而来的成员,因此继承前必须知道基类是什么。

一个类不能派生它本身。


4.防止被继承的方法

可以在类定义时,在类名后面跟上final关键字,就可以阻止该类作为基类。

class Base final{
public:
	virtual void test(){ cout << "base test" << endl; }
protected:
	int idata;
};
Base不能作为基类。

class Base{
public:
	virtual void test(){ cout << "base test" << endl; }
protected:
	int idata;
};

class Derived final:public Base{
public:
	Derived(){ idata = 0; }
	void test() override { cout << "derived test" << endl; }
};
Derived不能作为基类。


5.对象切割

当我们用一个派生类对象为一个基类对象初始化或赋值时,只有该派生类对象中的基类部分被拷贝、移动或赋值,他的派生类部分将被忽略掉。


6.派生类中的虚函数

一旦某个函数被声明成虚函数,则在所有派生类中它都是虚函数。

派生类中虚函数的返回类型必须与基类函数匹配。但是当类的虚函数返回类型是类本身的指针或引用时,可以不一样。不过这要求从继承类到基类的类型转换是可以访问的。

前面说过final关键字可以阻止成为基类,也可以阻止函数被继承类覆盖(该函数必须是virtual才能使用final)。

class Base{
public:
	virtual void test() final{ cout << "base test" << endl; }
protected:
	int idata;
};

class Derived final:public Base{
public:
	Derived(){ idata = 0; }
	void test() { cout << "derived test" << endl; } //错误,不能覆盖
};


7.回避虚函数的动态绑定

有些时候,我们希望对虚函数调用不进行动态绑定,则可以使用作用域运算符。

#include<iostream>  
#include <string>
#include <vector>
using namespace std;


class Base{
public:
	virtual void test(){ cout << "base test" << endl; }
protected:
	int idata;
};

class Derived final:public Base{
public:
	Derived(){ idata = 0; }
	void test() { cout << "derived test" << endl; } //错误,不能覆盖
};
int main()
{
	Base *a = new Derived();
	a->Base::test();
	Derived b;
	b.test();
	return 0;
}


8.纯虚函数

我们在函数体的位置书写=0可以将一个虚函数说明为纯虚函数。其中=0只能出现在类内部的虚函数声明语句处。

注意:一个纯虚函数无需定义,我们也可以为纯虚函数提供定义,但是函数体必须定义在类的外部。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值