>gpa; } 无效显示() { cout,c++,memory-management,C++,Memory Management" /> >gpa; } 无效显示() { cout,c++,memory-management,C++,Memory Management" />

类对象成员函数的内存分配 一个简单的C++程序. #include <iostream> #include <string> using namespace std; class Student { float gpa; public: void read() { cin>>gpa; } void display() { cout<<"STUDENT GPA : "<<GPA<<endl; } }; void main() { Student s1; } #包括 #包括 使用名称空间std; 班级学生 { 浮动gpa; 公众: 无效读取() { cin>>gpa; } 无效显示() { cout

类对象成员函数的内存分配 一个简单的C++程序. #include <iostream> #include <string> using namespace std; class Student { float gpa; public: void read() { cin>>gpa; } void display() { cout<<"STUDENT GPA : "<<GPA<<endl; } }; void main() { Student s1; } #包括 #包括 使用名称空间std; 班级学生 { 浮动gpa; 公众: 无效读取() { cin>>gpa; } 无效显示() { cout,c++,memory-management,C++,Memory Management,首先,这显然是一个实现细节。我的意思是,不同的编译器或编译选项可能导致不同的值。 但是,由于这里没有虚函数(*),因此方法、构造函数和析构函数在对象本身中不需要任何空间 并且(在修复代码中的一些错误和警告后:main应该是int而不是void,并且GPA应该是GPA…)在32位体系结构(clang版本3.4.1)上仅显示sizeof: 但在64位体系结构上或使用#pragma pack(8) (*)仍然是一个实现细节,但虚拟函数通常被实现为vtables,表示虚拟函数表。这意味着对象包含指向该对

首先,这显然是一个实现细节。我的意思是,不同的编译器或编译选项可能导致不同的值。 但是,由于这里没有虚函数(*),因此方法、构造函数和析构函数在对象本身中不需要任何空间

并且(在修复代码中的一些错误和警告后:
main
应该是
int
而不是
void
,并且
GPA
应该是
GPA
…)在32位体系结构(clang版本3.4.1)上仅显示
sizeof

但在64位体系结构上或使用
#pragma pack(8)

(*)仍然是一个实现细节,但虚拟函数通常被实现为vtables,表示虚拟函数表。这意味着对象包含指向该对象的虚拟函数表的指针(仅1个指针),或直接包含该表的副本(每个虚拟函数一个指针)。构造函数不是虚拟的,不占用空间,但虚拟析构函数使用vtable中的一个条目。

首先,这显然是一个实现细节。我的意思是,不同的编译器或编译选项可能导致不同的值。 但是,由于这里没有虚函数(*),因此方法、构造函数和析构函数在对象本身中不需要任何空间

并且(在修复代码中的一些错误和警告后:
main
应该是
int
而不是
void
,并且
GPA
应该是
GPA
…)在32位体系结构(clang版本3.4.1)上仅显示
sizeof

但在64位体系结构上或使用
#pragma pack(8)

(*)仍然是一个实现细节,但虚拟函数通常被实现为vtables,表示虚拟函数表。这意味着对象包含指向该对象的虚拟函数表的指针(仅1个指针),或直接包含该表的副本(每个虚拟函数一个指针)。构造函数不是虚拟的且不占用空间,但虚拟析构函数使用vtable中的一个条目

但如果选中,则分配的内存略高于4字节

因为成员函数、构造函数和析构函数分配了一些内存

不正确。这是因为在您的情况下需要内存对齐,而在其他情况下是因为虚拟函数需要某种形式的表,需要指向它的指针。构造函数、析构函数和方法的内存成本只支付一次,而不是每个对象

如何计算所有函数的大小

事实并非如此

是否有可能通过减少这些额外的分配来优化代码

当然,但这对对象的大小没有影响

但如果选中,则分配的内存略高于4字节

因为成员函数、构造函数和析构函数分配了一些内存

不正确。这是因为在您的情况下需要内存对齐,而在其他情况下是因为虚拟函数需要某种形式的表,需要指向它的指针。构造函数、析构函数和方法的内存成本只支付一次,而不是每个对象

如何计算所有函数的大小

事实并非如此

是否有可能通过减少这些额外的分配来优化代码

当然,但这对对象的大小没有影响

对于对象s1,必须在主存中分配4个字节

它们没有。您只在单个函数中使用对象,不使用指针或引用对其进行操作,并且它只包含一个
float
字段,因此编译器可能决定将该字段存储在寄存器中,而不是内存中

另外,您实际上不使用该字段,因此编译器可能根本不分配变量和字段,因为这是一个不可观察的优化

要显示这一点,您可以查看(在x64上使用带有
-O3
的clang 3.3):

注意,这段代码所做的只是将EAX寄存器归零,这只是隐式的
返回0;

对于对象s1,必须在主存中分配4个字节

它们没有。您只在单个函数中使用对象,不使用指针或引用对其进行操作,并且它只包含一个
float
字段,因此编译器可能决定将该字段存储在寄存器中,而不是内存中

另外,您实际上不使用该字段,因此编译器可能根本不分配变量和字段,因为这是一个不可观察的优化

要显示这一点,您可以查看(在x64上使用带有
-O3
的clang 3.3):


请注意,此代码所做的只是将EAX寄存器归零,这只是隐式的
返回0;

您的意思是
s1
的大小高于
浮点的大小
?您是如何检查的?每个函数都占用一些空间,但它们与
s1
分开。函数的大小是generate的大小d机器代码。这些优化不能超出编译器的功能。您的意思是
s1
的大小大于
float
的大小?您是如何检查的?每个函数都占用一些空间,但它们与
s1
分开。函数的大小是生成的机器代码的大小。这些无法优化谢谢你的回答!我已经明白你说的了!但是我有一个疑问!假设我有
 int main()
 {
     Student s1;
     cout << "Size: " << sizeof(s1) << endl;
     return 0;
 }
main:
        xorl    %eax, %eax
        ret