C++类几种情况的内存布局
来源:互联网 发布:网络信息抓取 编辑:程序博客网 时间:2024/06/09 18:50
对于C++开发者来说,了解其内存是非常必要的,同时C++的多态(动态绑定)的原理也是很重要的。
C++内存布局:
需要了解的几种情况:
1、无虚函数,非继承;
class simple {public:void simple_fun1() {};void simple_fun2() {};private:int simple_a_;};
内存布局:
没有虚函数,没有继承,所以只有成员变量需要分配空间。
2、有虚函数,非继承;
class Base {public:virtual void func1() { std::cout << "Func1()" << std::endl; }virtual void func2() { std::cout << "Func2()" << std::endl; }virtual void func3() { std::cout << "Func3()" << std::endl; }private:int a_;};内存布局以及虚函数列表:
没有继承,有虚函数,所以有了虚函数列表vfptr,指向该类的虚函数列表,虚函数列表中记录当前类的虚函数;
3、无虚函数,继承;
class simple1 : public simple {public:void simple1_func1() {};private:int simple1_a_;};
内存布局:
普通的继承关系,而且基类中没有虚函数,所以不会生成虚函数列表,指向基类的和指向自身类的指针是同一个。
4、有虚函数,单继承;
class Derived : public Base {public:virtual void func2() { std::cout << "derived Func2()" << std::endl; }virtual void func4() { std::cout << "Func4()" << std::endl; }private:int b_;};内存布局以及虚函数和列表:
单继承中,基类有虚函数,所以首先是虚函数列表,然后是从基类继承过来的成员变量,最后才是自己的成员变量。
由于override了基类的func2(),所以在虚函数列表中可以开看到,func2的域是Derived,而不再是基类Base。
5、有虚函数,多继承(非虚拟继承);
class Derived2 : public Base {public:virtual void func1() { std::cout << "derived2 Func1()" << std::endl; }virtual void func5() { std::cout << "Func5()" << std::endl; }private:int c_;};class Derived3 : public Derived, public Derived2 {public:void func6() { std::cout << "Func6()" << std::endl; }private:int d_;};
内存布局:
从以上内存布局可以发现一些问题,就是属于Base的成员变量a_出现了两次,虽然生成的时候可以通过,但是在实际使用过程中容易造成二义性出错,所以这种用法是需要尽量避免的。
虚函数列表:
虚函数列表中也有同样的问题,两个虚函数列表,有重复的函数Base::func3(),在实际中也要尽量避免。
6、无虚函数,多继承,虚拟继承;
将以上的Derived类和Derived2类对Base的继承改为虚拟继承:
class Derived3 : public Derived, public Derived2 {public:void func6() { std::cout << "Func6()" << std::endl; }private:int d_;};内存布局:
最后一种情况使用了虚拟继承,内存布局就不同了,可以看出,一共有5个虚函数列表,在第一部分中(0~8),由两个虚函数列表和Derived的成员变量b_,第一个虚函数列表是Derived3类继承Derived类时生成的,第二个虚函数是Derived继承时Base生成的。
对于第二部分(12~20)同理,第三部分(24)则是Derived3自己的成员变量;
第四部分(28~32),则是Derived3间接继承Base生成的。
虚函数列表:
虚函数列表有点复杂,此处有点不明白,为什么会有负数出现,隐约能够看懂虚函数列表的指向。
从以上可以看到,在实例化一个类对象的时候,仅仅为类的成员变量和虚函数列表指针分配空间(虚函数的情况下),而成员函数属于整个类共有的,不会再对象中分配空间。因此,当虚函数更多的时候,占用的内存空间会更多,所以在实际项目中,关于类的继承体系的设计,需要考虑到这个方面。
如有问题,还请指正。
- C++类几种情况的内存布局
- C的内存布局
- 扫盲类的内存布局情况
- c/c++的内存布局
- C程序的内存布局
- C/C++的内存布局
- C程序代码的内存布局
- C/C++的内存布局
- C语言的内存布局
- C代码的内存布局
- C程序的内存布局
- C++ 内存布局占用情况
- 一个c程序的内存布局
- C语言程序的内存布局
- C语言程序的内存布局
- C语言程序的内存布局
- C语言程序的内存布局
- C语言程序的内存布局
- 1056. 组合数的和(15)
- Java设计模式--桥接模式
- 最优贸易
- 火柴棒等式
- 文章标题 HDU 4638 : Group (莫队算法)
- C++类几种情况的内存布局
- Spring IOC 之注解配置、单元测试
- Nginx Lua 三种重定向的使用及比较
- Linux中unzip解压出现乱码,mismatching "local" filename和continuing with "central" filename version
- MySQL的Query Cache
- C语言中变量名及函数名的命名规则
- centos升级glibc(升级到 2.17版)
- 以前写的代码感觉很有用
- 自定义一个MVC框架