C++:类

C++:类

1. 空类为什么是一个字节

C++编译器不允许对象为零长度。试想一个长度为0的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。如果有自定义的变量,变量将取代这个缺省成员。

2. 类中的字节对齐

和结构体类似, 类中存在字节对齐, 需要注意如果存在虚函数, 虚函数表占据4个字节。

#include <iostream>

using namespace std;

class A { // vfptr:4字节
public:
    virtual void vfunc1()
    {
        cout << "A::vfun1" << endl;
    }
    virtual void vfunc2()
    {
        cout << "A::vfun2" << endl;
    }
    void func1();
    void func2();
private:
    int m_data1, m_data2; // 8字节
};
 
class B : public A { // 虚函数表:4字节
public:
    virtual void vfunc1();
    void func1();
private:
    int m_data3; // 4字节 + 从父类继承的8字节
};
 
class C: public B { // 虚表:4字节
public:
    virtual void vfunc2();
    void func2();
private:
    int m_data1, m_data4; // 8字节 + 从父类继承的12字节
};

class D
{};

class F
{
public:
    virtual void fun();
    bool b; // 由于存在虚表, 字节对齐, 8个字节
};

int main()
{
    cout << sizeof(A) << endl; // 12
    cout << sizeof(B) << endl; // 16
    cout << sizeof(C) << endl; // 24
    cout << sizeof(D) << endl; // 1
    cout << sizeof(F) << endl; // 8

    system("pause");
    return 0;
}

指定字节对齐

#pragma pack(4); // 指定4字节对齐

 

3. 类中的虚函数表

虚函数表是一个函数指针类型的数组, 类中的第一个成员是虚函数表首元素的地址:vfptr。

typedef void (*pFunc)(void);
A a;
int *p = (int *)&a; // 获取对象的地址
int *fun = (int *)(*p); // 获取虚表的地址
((pFunc)(fun[0]))(); // 获取虚表中的表项--偏移

 

4. 类中的继承

总结——公有、私有、保护继承:
 
特征
公有继承
保护继承
私有继承
公有成员
派生类的公有成员
派生类的保护成员
派生类的私有成员
保护成员
派生类的保护成员
派生类的保护成员
派生类的私有成员
私有成员
只能通过基类的接口访问
只能通过基类的接口访问
只能通过基类的接口访问
是否隐式向上转换
是(只能在派生类中)
否(必须显式)

 

 5. 类的虚继承

https://www.cnblogs.com/BeyondAnyTime/archive/2012/06/05/2537451.html

https://www.cnblogs.com/yanqi0124/p/3829964.html

 

 

 

 

 

 

 

 

 
posted @ 2020-09-03 22:17  x_Aaron  阅读(203)  评论(0)    收藏  举报