C++ 继承与多态 续

动态联编

联编是指计算机程序自身彼此关联的过程,是把一个标识符名和一个存储地址联系在一起的过程,也就是把一条消息和一个对象的操作相结合的过程

如果使用基类指针或引用指明派生类对象并使用该指针调用虚函数(成员选择符用箭头号“->”),则程序动态地(运行时)选择该派生类的虚函数,称为动态联编;动态联编亦称滞后联编

如果使用对象名和点成员选择运算符 “.” 引用特定的一个对象来调用虚函数,则被调用的虚函数是在编译时确定的(称为静态联编

class Object
{
private:
	int value;
public:
	Object(int x = 0) :value(x)
	{}
	virtual void add()
	{
		cout << "Object::add" << endl;
	}
	virtual void fun()
	{
		cout << "Object::fun" << endl;
	}
};
class Base :public Object
{
private:
	int num;
public:
	Base(int x = 0) :Object(x + 10), num(x)
	{}
	virtual void add()
	{
		cout << "Base::add" << endl;
	}
	virtual void fun(int x)
	{
		cout << "Base::fun(int x)" << endl;
	}
};

int main()
{
	Object* op = NULL;
	Base* bp = NULL;
	Base base(10);
	
	op = &base;
	op->add();
	op->fun();
	//op->fun(12); error
	//静态联编过程

	bp = &base;
	bp->add();
	//bp->fun(); error 此处将父类方法隐藏
	bp->fun(12);
}

在这里插入图片描述
对于Object,仅有两个虚表函数,所以无法调用op->fun(12);,对于bp,去调用add()是正确的,但是去调用fun()的时候,在编译过程中由于Base中的虚函数与Object中的虚函数,同名而不同参;此时编译发生同名隐藏,会默认为是有参数的fun()函数bp->fun(12);是正确的

若使用bp去调用无参的fun()函数,则通过此方式bp->Object::fun();来进行调用

非虚析构函数

class Object
{
private:
	int value;
public:
	Object(int x = 0) :value(x)
	{
		cout << "Create Object" << this << endl;
	}
	virtual void add()
	{
		cout << "Object::add" << endl;
	}
	virtual void fun()
	{
		cout << "Object::fun" << endl;
	}
	~Object()
	{
		cout << "Destroy Object" << this << endl;
	}
};
class Base :public Object
{
private:
	int num;
public:
	Base(int x = 0) :Object(x + 10), num(x)
	{
		cout << "Create Base" << this << endl;
	}
	virtual void add()
	{
		cout << "Base::add" << endl;
	}
	virtual void fun(int x)
	{
		cout << "Base::fun(int x)" << endl;
	}
	~Base()
	{
		cout << "Destroy Base" << this << endl;
	}
};

int main()
{
	Object* op = new Base(10);
	op->add();

	delete op;
	op = NULL;
	return 0;
}

在这里仅调用了Object的析构函数,而没有调用Base的析构函数
在这里插入图片描述
析构函数为非虚函数,系统在编译过程中,根据op的类型进行绑定,则只会调动Object的虚构函数

若为了达到运行时的多态,则需要将析构函数定义为虚函数

	virtual ~Object()
	{
		cout << "Destroy Object" << this << endl;
	}

在这里插入图片描述

纯虚函数

纯虚函数是指被标明为不具体实现的虚拟成员函数,它用于这样的情况:定义一个基类时,会遇到无法定义基类中虚函数的具体实现,其实现依赖于不同的派生类

定义纯虚函数的一般格式如下:

virtual 返回类型 函数名(参数表)= 0; “=0”表明程序员将不定义该函数,函数声明是为派生类保留一个位置。“=0”本质上是将指向函数体的指针定为 “NULL”

抽象类

含有纯虚函数的基类不能用来定义对象的

纯虚函数没有实现部分,不能产生对象,所以含有纯虚函数的类是抽象类

带纯虚函数的类称为抽象类,抽象类是一种特殊的类,它是为了抽象和设计的目的而建立的,它处于继承层次结构的较上层,抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限

抽象类的主要作用是将有关的组织在一个继承层次结构中,由它来为它们提供一个公共的根,相关的子类是从这个根派生出来的

抽象类刻画了一组子类的操作接口的通用语义,这些语义也传给子类;一般而言,抽象类只描述这组子类共同的操作接口,而完整的实现留给子类

抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出,如果派生类没有重新定义纯虚函数,而派生类只是继承基类的纯虚函数,则这个派生类依然还是一个抽象类,如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体类了

抽象类的规定

  • 抽象类只能用作其他类的基类,不能建立抽象类对象
  • 抽象类不能用作参数类型、函数返回类型或显示转换的类型
  • 可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值