C++-动态联编

静态联编

束定:程序中的操作调用(如函数调用)与执行该操作代码间的关系(简单来说就是在函调用时能找到相应代码的位置)

静态联编就是联编工作在编译阶段完成 也就是在程序运行之前就已经确定好了调用这个函数要去哪找
编译阶段就必须确定程序中的操作调用(如函数调用)与执行该操作代码间的关系

下面代码类B继承类A 创建了一个类A类型的指针pa
先pa指针指向类A对象a 调用f()函数 结果是A 再将pa指向类B对象b的地址 调用f()函数 结果还是A 我们会发现地址变了 但是结果没变

class A

{
public:

	void f() { cout << "A" << endl; }

};

class B:public A

{ public:

 void f() { cout << "B" << endl; }

};

void main()

{
	A* pa = NULL;

	A a; 
	B b;

	pa = &a; cout << pa<<endl;
	pa->f();
	pa = &b; cout << pa<<endl;
	pa->f();
}

在这里插入图片描述
通过对象指针进行的普通成员函数的调用,仅仅与指针的类型有关,而与此刻指针正指向什么对象无关。要想实现当指针指向不同对象时执行不同的操作,就必须将基类中相应的成员函数定义为虚函数,进行动态联编

动态联编

动态联编就是程序在运行的时候知道该调用哪个函数
相较于静态联编 动态联编在编译时只知道要运行的函数名字 并不能确定要去哪运行代码 只有地址确定了才行 动态联编对成员函数的选择是基于对象的类型
动态联编要求派生类和基类中要动态联编的方法函数的返回值类型,参数个数,参数类型,函数名等都必须相同 如果不满足这些条件,派生类中的虚函数将丢失其虚特性,在调用时进行静态联编。

动态联编 只能通过指针或引用标识对象来操作虚函数
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数

在基类如果在函数前加了virtual 用基类指针指向子类对象时 如果调用的基类函数有virtual 那就是该函数调用时动态在程序运行时联编 而如果没有加virtual就是静态在编译时联编 不用管该函数是否时通过其他函数调用 如下
f1函数如果加了virtual就是调用C类的 没加就是调用B类的

class A

{
public:

	virtual void f() { cout << "A" << endl; }

};

class B:public A

{ 
public:

 virtual void f() { cout << "B" << endl; }

};

void main()

{
	A* pa = NULL;

	A a; 
	B b;

	pa = &a; cout << pa<<endl;
	pa->f();
	pa = &b; cout << pa<<endl;
	pa->f();
}

在这里插入图片描述

如果C类继承B类 B类继承A类 用A类指针指向C类 然后用A类指针调用f函数
因为是指向C类对象 且在A类中f函数是virtual 所以动态调用C类中的f函数 但是C类中没有f函数 所以调用它的父类B类中的f函数 但是由于f函数调用了f1函数 A类中的f1函数又没有virtual 所以在B类的f函数中调用f1函数时不能进行动态联编 就只能调用B类中的f1函数了 如果A类中有virtual 那么就是调用C类中的f1函数

class A

{
public:

	virtual void f() { cout << "A" << endl; f1();}
	 void f1() { cout << "A1" << endl; }

};

class B :public A

{
public:

	void f() { cout << "B" << endl; f1(); }
	 void f1() { cout << "B1" << endl; }

};
class C :public B

{
public:

	//void f() { cout << "C" << endl; }
	void f1() { cout << "C" << endl; }

};

void main()

{
	A* pa = NULL;

	A a;
	B b;
	C c;

	pa = &a; cout << pa << endl;
	pa->f();
	pa = &b; cout << pa << endl;
	pa->f();
	pa = &c; cout << pa << endl;
	pa->f();
}

在这里插入图片描述

如果A类中f1函数有virtual 就是调用C类中的f1函数

class A

{
public:

	virtual void f() { cout << "A" << endl; f1();}
	virtual void f1() { cout << "A1" << endl; }

};

class B :public A

{
public:

	void f() { cout << "B" << endl; f1(); }
	 void f1() { cout << "B1" << endl; }

};
class C :public B

{
public:

	//void f() { cout << "C" << endl; }
	void f1() { cout << "C" << endl; }

};

void main()

{
	A* pa = NULL;

	A a;
	B b;
	C c;

	pa = &a; cout << pa << endl;
	pa->f();
	pa = &b; cout << pa << endl;
	pa->f();
	pa = &c; cout << pa << endl;
	pa->f();
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值