前言
猪场最爱考的内容, 亲测.
结构体大小
先来看个基础的:
#include <iostream>
#pragma pack (8)
using namespace std;
struct A {
char a;
int b;
double c;
};
int main() {
// 1: 13
// 2: 14
// 4: 16
// 8: 16
cout << sizeof(A) << endl;
}
按理说, char 1个byte, int 4个byte, double 8个byte. 应该是13个字节, 为什么会有别的答案. 甚至没有
#pragma pack (v)
的情况下都是16. 原因就在于字节对齐. 关于字节对齐为啥存在, 简单来说, 就是数据都是一块一块读的, 不是一个一个.
那么如何得出呢, 其实很简单, 1的情况下, 是多少就是多少. 2的话, 补成第一个大于13的2的倍数, 也就是14, 4的话, 第一个大于13的4的倍数, 也就是16, 以此类推. 而64位默认是8字节对齐.
然后你会说, 就这?
类大小
那么下面这个呢?
class B {
public:
B(char a, int b, double c) : a(a), b(b), c(c) {}
static int x;
virtual void hello() {};
private:
char a;
int b;
double c;
};
你可能会说还是16, 因为函数和静态变量不算在大小内. 你答对了一半, 函数是不算, 但是virtual关键字导致了虚指针的产生, 而我的mac是64位, 指针占8个字节, 所以答案是24.
那么继承一下呢?
class C : public B {
public:
C(char a, int b, double c, int d) : B(a, b, c), d(d) {}
virtual void hello() {}
private:
int d;
};
你会说28, 不过注意, 64位默认8字节对齐, 所以是32哦. 你会说, 不对, 这里有virtual, 多一个虚指针. 不对, 这里只有一个虚指针, 继承来的, 指向自己的虚表. 所以如果面试官问你, 为什么基类指针可以动态调用子类函数, 你就可以从虚指针来作答.
虚继承
如果是菱形继承怎么办?
class B {
public:
B(char a, int b, double c) : a(a), b(b), c(c) {}
static int x;
virtual void hello() {};
private:
char a;
int b;
double c;
};
class C : public B {
public:
C(char a, int b, double c, int d) : B(a, b, c), d(d) {}
void hello() override {}
private:
int d;
};
class D : public B {
public:
D(char a, int b, double c, int d) : B(a, b, c), d(d) {}
void hello() override {}
private:
int d;
};
class E : public C, D {
public:
E(char a, int b, double c, int d1, int d2, int d) : C(a, b, c, d1), D(a, b, c, d2), d(d) {}
void hello() override {}
private:
int d;
};
结果64怎么算, 首先B 24, C 28, D 28, E 28 + 28 + 4 = 60, 然后8字节对齐, 64. 如果4字节对齐就是60. 注意, 这里C, D都有虚指针, 被E继承.
如果变化下, 改成虚继承. 先来看输出:
class C : virtual public B {
public:
C(char a, int b, double c, int d) : B(a, b, c), d(d) {}
void hello() override {}
private:
int d;
};
class D : virtual public B {
public:
D(char a, int b, double c, int d) : B(a, b, c), d(d) {}
void hello() override {}
private:
int d;
};
image
是不是懵了, C, D变大了, E变小. 先来看E, 它继承了C, D的独有变量,但是没有继承他们从B得到的, 而是直接从B获取一份内容, 这样就是3个虚指针, B的变量, C和D的变量, 自己的变量, 也就是24+13+4+4+4=49, 8字节对齐, 等于56. 那么40怎么来的? 其实2个虚指针+B的变量+C的变量, 16+13+4=33, 8字节对齐, 40.
网友评论