运算符方法会占用c++对象中的内存吗
do operator methods occupy memory in c++ objects?
假设我有一些简单的类/结构,除了数据和一些选择的运算符之外什么都没有。如果我理解的话,C++中只有数据的基本结构,就像C一样,占用的内存和成员一样多。例如,
struct SomeStruct { float data; }
sizeof(SomeStruct) == sizeof(float); // this should evaluate to true
我想知道的是,在类中添加运算符是否会使对象在内存中变得更大。例如
struct SomeStruct
{
public:
SomeStruct & operator=(const float f) { data = f; return this; }
private:
float data;
}
CCD_ 1评估为true仍然是真的吗?是否存在不会增加内存中对象大小的运算符/方法?
结构可能不一定只有其成员那么大(考虑填充和对齐),但您基本上是正确的,因为:
函数不是数据,也不"存储"在对象类型中
也就是说,在向类型中添加虚拟函数的情况下,请注意添加虚拟表指针。这是该类型的一次性大小增加,在添加更多虚拟函数时不会重新应用。
我想知道的是,向类中添加运算符是否会使对象在内存中变得更大。
答案是"取决于情况"。
如果在添加函数之前类不是多态的,并且这个新函数使类保持非多态性,那么添加这个非多态函数对类实例的大小没有任何影响。
另一方面,如果添加这个新函数确实使类具有多态性,那么这个添加将使类的实例更大。大多数C++实现都使用虚拟表,简称vtable。多态类的每个实例都包含一个指向该类的vtable的指针。非多态类的实例不需要,因此不包含vtable指针。
最后,向已经多态的类中添加另一个虚拟函数并不会使类实例变大。这个添加确实使该类的vtable变大,但vtable本身不是实例的一部分。vtable指针是实例的一部分,而该指针已经是类布局的一部分了,因为类已经是多态的。
当我学习C++和OOP时,我在某个地方(一些糟糕的来源)读到C++中的对象本质上与内部有函数指针的C结构相同。它们在功能上可能是这样的,但如果它们真的是这样实现的,那将是巨大的空间浪费,因为所有对象实例都必须存储相同的指针。
方法代码存储在一个中心位置,C++只是让它看起来很方便,好像每个实例都有自己的方法。(运算符本质上是具有不同语法的函数)。
在类中定义的方法和运算符不会增加实例化对象的大小。你可以自己测试:
#include <iostream>
using namespace std;
struct A {
int a;
};
struct B {
int a;
//SOME RANDOM METHODS AND OPERATORS
B() : a(1) {cout<<"I'm the constructor and I set 'a' to 1"<<endl;}
void some_method() const { for(int i=0;i<40;i++) cout<<"loop";}
B operator+=(const B& b){
a+=b.a;
return *this;
}
size_t my_size() const { return sizeof(*this);}
};
int main(){
cout<<sizeof(A)<<endl;
cout<<B().my_size()<<endl;
}
64位系统的输出:
4
I'm the constructor and I set 'a' to 1
4
===>尺寸不变。
- 迭代时从向量和内存中删除对象
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 对具有动态分配的内存和析构函数的类对象的引用
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 内存清理程序报告全局对象构造中未初始化值的使用
- 如何删除列出的"QGraphicsPathItem"对象以控制进程内存使用情况?
- 有没有办法列出所有共享内存对象的名称?
- 我的共享内存对象保存在哪里
- boost共享内存对象中的指针
- 创建 boost::interprocess 共享内存对象的非共享副本
- 提升中的异常:进程间,共享内存对象删除
- 自动C++内存/对象实例管理?智能指针
- 将矢量或任何其他容器存储在boost进程间共享内存对象中
- OpenCL:减少示例,并保留内存对象/将cuda代码转换为OpenCL
- boost::创建托管共享内存对象时出现进程间ubuntu异常
- 用户可能无法在 Linux 系统上打开共享内存对象的原因
- 如何测试boost共享内存对象是否被删除?
- 将指向结构体或内存对象的空指针强制转换为新结构体
- Apache模块共享内存对象