网站文件保护怎么做,移动应用开发行业发展趋势,如何做网站授权网址,学校网站搭建OVERVIEW 多态/虚函数/虚函数表1.虚函数引入后类发生的变化#xff1f;2.虚函数表的生成时机和生成原因#xff1f;3.虚函数表指针赋值的时机#xff1f;4.类对象在内存中的布局#xff1f;5.虚函数的工作原理和多态性的体现#xff1f;6.其他问题 多态/虚函数/虚函数表 n… OVERVIEW 多态/虚函数/虚函数表1.虚函数引入后类发生的变化2.虚函数表的生成时机和生成原因3.虚函数表指针赋值的时机4.类对象在内存中的布局5.虚函数的工作原理和多态性的体现6.其他问题 多态/虚函数/虚函数表 non-virtual不希望derived class 重新定义该它virtual希望derived class重新定义它并且你对它已经有了默认的定义pure-virtual希望derived class一定要重新定义它
1.虚函数引入后类发生的变化
class A {
public:void func1() {}void func2() {}
public:virtual void vfunc() {}
};
sizeof(A) 4;//x86
sizeof(A) 8;//linuxgcc当一个或者多个虚函数加入到类中之后编译器会向类中插入一个看不见的成员变量void *vptr虚函数表指针virtual table ptr
2.虚函数表的生成时机和生成原因
当某个类中存在至少一个虚函数的时候在编译期间编译器就会为类A生成一个虚函数表 vtblvirtual table
虚函数表会一直伴随着类经过编译、链接、生成可执行文件、装载到内存中来
3.虚函数表指针赋值的时机 对于有虚函数的类在编译期时编译器向类的构造函数中安插为vptr赋值的语句在创建类对象时使得vptr指向类的vtbl
4.类对象在内存中的布局
class A {
public:void func1() {}void func2() {};
public:virtual void vfunc1() {}virtual void vfunc2() {}virtual ~A() {}
private:int m_a;int m_b;
};
sizeof(A) 12;类A在内存中的布局
5.虚函数的工作原理和多态性的体现
多态性多态必须存在虚函数没有虚函数绝不可能存在多态并且只有调用虚函数时才有存在多态性的可能 从代码上看多态的体现
父类中有虚函数、子类中也有该同名的虚函数当通过父类指针new子类对象 or 通过父类引用绑定子类对象时如果用父类指针来调用该虚函数那么调用的是子类的虚函数
class Base {
public:virtual void myvirfunc() {}
};Base *ptr new Base();
ptr-myvirfunc();//多态
Base base;
base.myvirfunc();//非多态
Base *pbase base;
pbase-myvirfunc();//多态从表现形式上看多态的体现
程序中既存在父类也存在子类父类中必须含有虚函数子类中也必须重写父类中的虚函数父类指针指向子类对象或者父类引用绑定/指向子类对象当通过父类的指针or引用调用子类中重写的虚函数时就能看出多态性的表现了调用的是子类的虚函数
class Derive : public Base {
public:virtual void myvirfunc();
};
//父类指针指向子类对象1
Derive derive;
Base *pbase1 derive;
pbase1-myvirfunc();
//父类指针指向子类对象2
Base *pbase2 new Derive();
pbase2-myvirfunc();
//父类引用绑定子类对象
Derive derive2;
Base refer_base derive2;
refer_base.myvirfunc();6.其他问题
问当进行多重继承时子类对象有几个虚函数表指针子类有几个虚函数表答在进行多重继承时子类对象会包含每个父类的成员变量和虚函数表指针。
如果每个父类都有虚函数那么每个父类都会有一个虚函数表子类对象会包含每个父类的虚函数表指针因此子类对象会有多个虚函数表指针每个指针指向相应的虚函数表。
如果某个父类没有虚函数那么子类对象就不会包含该父类的虚函数表指针只会包含其他父类的虚函数表指针和成员变量。
问如果将虚继承虚基类融入进来这时又多出来了虚基类表指针和虚基类表那么虚基类表指针在对象内存中的布局浅谈C类中的内存布局https://www.zhihu.com/tardis/zm/art/380147337?source_id1005