步骤1:命令行安装这个支持多编译的包
sudo apt-get install gcc-multilib g++-multilib
步骤2:g++编译的时候加上 -m32 参数
g++ -m32 heheda.cpp -o heheda
运行:./heheda 时就是32位的了
#include
using namespace std;
class A{
};
int main() {
std::cout<< sizeof(A) <
【总结】c++要求每个实例在内存中都有独一无二的地址。空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
#include
using namespace std;
class A{
public:
virtual void Test();
};
int main() {
std::cout<< sizeof(A) <
64位系统下,8字节;32位系统下,4字节
#include
using namespace std;
class A{
public:
virtual void Test();
virtual void TestA();
};
int main() {
std::cout<< sizeof(A) <
64位系统下,8字节;32位系统下,4字节
【总结】C++ 类中有虚函数的时候有一个指向虚函数的指针(vptr),在32位系统分配指针大小为4字节。无论多少个虚函数,只有这一个指针,4字节。
#include
using namespace std;
class A{
public:
virtual void Test();
virtual void TestA();
private:
int age;
bool sex;
};
int main() {
std::cout<< sizeof(A) <
64位系统下,16字节;32位系统下,12字节
① 以32位系统来解释:int 占4字节,bool占一字节,补齐3字节,虚函数的指针(vptr)的大小为4字节,所以为12字节
#include
using namespace std;
class A{
public:
virtual void Test();
virtual void TestA();
private:
int age;
bool sex;
bool bChild;
};
int main() {
std::cout<< sizeof(A) <
64位系统下,16字节;32位系统下,12字节
① 以32位系统来解释:int 占4字节,bool sex占一字节,bool bChild占一字节,sex和bChild紧挨着放一起,补齐2字节,虚函数的指针(vptr)的大小为4字节,所以为12字节
class A{
public:
virtual void Test();
virtual void TestA();
private:
bool bChild;
int age;
bool sex;
};
int main() {
std::cout<< sizeof(A) <
64位系统下,24字节;32位系统下,16字节
① 以32位系统来解释:bool bChild占一字节补齐3字节,int 占4字节,bool sex占一字节补齐3字节,虚函数的指针(vptr)的大小为4字节,所以为16字节
【例子1】:
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
private:
int a;
char *p;
};
64位系统下,24字节;32位系统下,12字节
① 以32位系统来解释:在32位系统分配指针大小为4字节。虚函数的指针(vptr)的大小为4字节,int 占4字节,char类型的指针p的大小为4字节,所以为12字节
② 以64位系统来解释:在64位系统分配指针大小为8字节。虚函数的指针(vptr)的大小为8字节,int 占4字节,补齐4字节,char类型的指针p的大小为8字节,所以为24字节
class CChild : public CBase
{
public:
CChild(void);
~CChild(void);
virtual void test();
private:
int b;
};
64位系统下,32字节;32位系统下,16字节
【注意】子类的大小是本身成员变量的大小加上父类的大小。
① 以32位系统来解释:父类的大小为12字节,int 占4字节,所以为16字节
② 以64位系统来解释:父类的大小为24字节,int 占4字节,所以为32字节(往往被调整到系统的整数倍。)
【例子2】:
class A {};
class B{};
class C:public A{
virtual void fun()=0;
};
class D:public B,public C{};
64位系统下,A占1字节,B占1字节,C占8字节,D占8字节;
32位系统下,A占1字节,B占1字节,C占4字节,D占4字节;
class A {};
class B{
private:
bool c;
int a;
bool b;
};
class C:public A{
virtual void fun()=0;
};
class D:public B,public C{};
64位系统下,A占1字节,B占12字节,C占8字节,D占24字节;
32位系统下,A占1字节,B占12字节,C占4字节,D占16字节;
class A {};
class B{
private:
int a;
bool b;
bool c;
};
class C:public A{
virtual void fun()=0;
};
class D:public B,public C{};
64位系统下,A占1字节,B占8字节,C占8字节,D占16字节;
32位系统下,A占1字节,B占8字节,C占4字节,D占12字节;
【测试一】
#include
using namespace std;
// ====== 测试一 ======
class Test {
private:
int n;
char c;
short s;
};
int main() {
Test t21;
cout << sizeof(t21) << endl;//x64:8 x86:8
return 0;
}
64位系统下,8字节
32位系统下,8字节
【测试二】
#include
#include
using namespace std;
// ====== 测试二 ======
class Test {
private:
int n;
char c;
short s;
static int a;
};
int main() {
Test t21;
cout << sizeof(t21) << endl;//x64:8 x86:8
return 0;
}
64位系统下,8字节
32位系统下,8字节
【总结】静态变量不计算在类所占内存的大小。
【原因】
① static修饰的静态变量:不占用内容
② 由于类的静态成员变量编译时被分配到静态/全局区,静态成员变量是属于类的,所有对象共用一份,不计入类的内存空间。
【测试三】
#include
#include
using namespace std;
// ====== 测试三 ======
class Test {
public:
//构造函数
Test() {
}
//普通成员
int func0() {
return n;
}
//友元函数
friend int func1();
//常成员函数
int func2() const {
return s;
}
//内联函数
inline void func3() {
cout << "inline function" << endl;
}
//静态成员函数
static void func4() {
cout << "static function" << endl;
}
//析构函数
~Test() {
}
private:
int n;
char c;
short s;
static int a;
};
int func1() {
Test t;
return t.c;
}
int main() {
Test t22;
cout << sizeof(t22) << endl;//x64:8 x86:8
return 0;
}
64位系统下,8字节
32位系统下,8字节
【总结】由于C++中成员函数和非成员函数都是存放在代码区的,类中一般成员函数、友元函数,内联函数还是静态成员函数都不计入类的内存空间
【原因】类内部的成员函数:
① 普通函数:不占用内存。
② C++编译系统中,数据和函数是分开存放的(函数放在代码区;数据主要放在栈区或堆区,静态/全局区以及文字常量区也有),实例化不同对象时,只给数据分配空间,各个对象调用函数时都都跳转到(内联函数例外)找到函数在代码区的入口执行,可以节省拷贝多份代码的空间
③ 数据主要放在栈区或堆区,有可能是堆,也有可能是栈。这取决于实例化对象的方式:
A a = new A(); //堆
int a; //栈
④ 内联函数(声明和定义都要加inline)也是存放在代码区。inline与成员函数是否占用对象的存储空间无关
【测试四】
#include
#include
using namespace std;
// ====== 测试四 ======
class Test {
public:
Test() {
}
int func0() {
return n;
}
friend int func1();
int func2() const {
return s;
}
inline void func3() {
cout << "inline function" << endl;
}
static void func4() {
cout << "static function" << endl;
}
//虚函数,需要一个虚函数指针的开销
virtual void func5() {
cout << "virtual function1" << endl;
}
virtual void func6() {
cout << "virtual function2" << endl;
}
~Test() {
}
private:
int n;
char c;
short s;
static int a;
};
int func1() {
Test t;
return t.c;
}
int main() {
Test t22;
cout << sizeof(t22) << endl;//x64:16 x86:12
return 0;
}
64位系统下,16字节
32位系统下,12字节
【总结】由于出现了虚函数,故类要维护一个指向虚函数表的指针。虚函数指针和虚基类指针也属于数据部分。
【原因】类内部的成员函数:
⑤ 虚函数:要占用4个字节(32位系统)或8个字节(64位系统),用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的。
C++中类所占的内存大小以及成员函数的存储位置_为什么成员函数不占用类的空间_SOC罗三炮的博客-CSDN博客https://blog.csdn.net/luolaihua2018/article/details/110736211