构造函数调用虚函数采用动态联编(C++关于动态联编)

本文目录
C++关于动态联编
动态联编其实也就是动态多态性,它是通过基类指针和虚函数实现的,即先定义一个基类指针,然后通过基类指针指向不同的类对象,调用对应的虚函数。
例如:
void main()
{ A a; //定义类A对象a
B b; //定义类B对象b
C c; //定义类C对象c
A *p;//定义一个基类指针p
p=&a //基类指针p指向基类A的对象a
p-》my(); //此时调用的是基类A的my()函数
p=&b //基类指针p指向类B的对象b
p-》my(); //此时基类指针p调用的是类B的my()函数
p=&c //基类指针p指向类C的对象c
p-》my(); //此时基类指针p调用的是类C的my()函数
}
c++ 中如何调用基类的虚函数
下面是例子:
#include 《iostream》
using namespace std;
class A
{
public:
A(int i) { n=i; }
A(){ n=1;}
virtual void f(){ std::cout《《"A.f() is used"《《endl;}
void g(){ std::cout《《"A.g() is used"《《endl;}
void k(){ std::cout《《"A.k() is used"《《endl;}
private:
int n;
};
class B:public A
{
public:
B(int i) { n=i; }
B(){ n=1;}
void f(){ std::cout《《"B.f() is used"《《endl;}
void g(){ std::cout《《"B.g() is used"《《endl;}
void h(){ std::cout《《"B.h() is used"《《endl;}
virtual void j(){ std::cout《《"B.h() is used"《《endl;}
private:
int n;
};
class C
{
public:
C(int i) { n=i; }
C(){ n=1;}
void w(){ std::cout《《"C.w() is used"《《endl;}
private:
int n;
};
int main()
{
B b;
b.k(); //b显然能看到A中的k()
A *a;
a=&b
a-》f(); //a看到的是B的f()
a-》A::f(); //a看到的是A的f()
a-》g(); //a看到的是A的g()
a-》h(); //a看不到B的h()
a-》j(); //a看不到B的虚拟函数j()
cout《《a-》C::n《《endl; //看不到
a-》C::w(); //看不到
while(1)
{
}
}
一个类的对象中是没有关于普通成员函数的指针的slot,只有成员变量还有虚表指针,类的成员函数的代码定义在PE文件的代码区,所以从程序加载时,就已经分配好了内存用于存放这些代码;代码运行时所需要的内存,比如栈、堆等等,则是代码运行时才分配的;对于某个类的所有对象来说,类成员函数只在内存中有一份拷贝,所有的对象都共享同一份成员函数的代码。同一个类的不同的对象之间的差异仅仅是通过成员变量来体现的。c++实现成员函数的时候实际上用到了一个技巧——this指针。this指针是当前调用成员函数的对象首地址,我们知道通过这个地址可以访问到对应对象的成员变量。那么成员函数如何区分this究竟指向哪个对象呢?技巧就在于,c++背后把成员函数当做普通函数一样调用,除了传入实际的参数外,还把所属对象的指针作为参数this传入,函数内部通过显示的或者隐含的方式访问对象成员。
c++中怎么理解动态联编和静态联编
通常来说联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。
静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针的类型,C语言中,所有的联编都是静态联编,并且任何一种编译器都支持静态联编。
动态联编是指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定,动态联编对函数的选择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编译结果。C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚拟函数就必须要使用动态联编了。
多态联编:字面的含义是具有多种形式或形态。C++多态有两种形式,动态多态和静态多态;动态多态是指一般的多态,是通过类继承和虚函数机制实现的多态;静态多态是通过模板来实现,因为这种多态实在编译时而非运行时,所以称为静态多态。
关于C++虚拟函数或者可能是联编的问题
输出 B A
基类的析构函数是动态联编虚析构函数,所以当撤销p时,先调用派生类的析构函数,再调用基类的析构函数。
当基类的析构函数不是虚析构函数,p析构时,因为p是基类指针,所以只调用基类析构函数,而不调用派生类的析构函数。
至于A的析构函数是怎样找到A::print,我觉得是查找需函数表。嘿嘿~~~
另外print不是被重载,是叫覆盖。你可以查一下概念。
C++运行时多态的选择题,帮帮新手吧
答案是D
解释:
A:构造函数不能声明为虚函数,但在构造函数中可以调用虚函数.在构造函数或析构函数中调用虚函数,将采用静态联编
B,C,D:构造函数不能声明为虚函数,但析构函数可以声明为虚函数.
当基类的析构函数声明为虚函数时,无论派生类是否使用virtual关键字说明,派生类的析构函数一定是虚函数,而且,如果满足动态联编的其他条件,对虚析构函数的调用将采用动态联编

更多文章:
全球新冠肺炎疫情背景下航运发展(盐田港复苏日志:半年历劫从“低谷”到“爆仓” 疫情之后巨轮如何越洋航行)
2026年9月7日 17:10
matlab求解带字母参数方程组(我想matlab求一个关于x,y的方程组 ab c d f e h m n 都是参数)
2026年9月7日 16:30
oracle中的循环语句(下面哪个不是oracle程序设计中的循环语句 a for)
2026年9月7日 15:30
电脑里2个系统怎么删除一个(电脑开机显示有两个系统,如何删除一个)
2026年9月7日 12:20
scrollthrough意思(“scroll”是什么意思)
2026年9月7日 08:00
怎么激活keygen(注册机如何激活cad2008一个简单激活cad2008的方法)
2026年9月7日 06:30
vba编写excel插件(excel vba中能否动态创建控件)
2026年9月7日 04:40





