每个对象的实例都在内存中重复方法吗?如果是这样,这是可以避免的吗?
Are methods duplicated in memory for every instance of an object? If so, can this be avoided?
假设我有一个大量存在的对象,它本身存储的数据很少,但需要几个较大的函数来作用于它。
class Foo
{
public:
bool is_dead();
private:
float x, y, z;
bool dead;
void check_self();
void update_self();
void question_self();
};
我可以期待编译器的什么行为-每个新的Foo对象都会导致其方法的副本被复制到内存中吗?
如果是,在避免重复的同时管理类特定的(private-like)函数有什么好的选择?如果没有,你能详细说明一下吗?
c++方法是简单的函数(有一个关于this
的约定,它经常成为隐式的第一个参数)。
函数大多是机器码,从某个特定地址开始。起始地址是调用函数所需要的全部内容。
所以对象(或它们的虚函数表)最多只需要调用函数的地址。
当然,函数会出现在某个位置(在文本段中)。
但是对象不需要为该函数提供额外的空间。如果函数不是虚函数,则每个对象不需要额外的空间。如果函数是虚函数,则对象有一个单个虚函数表(每个虚类)。通常,每个对象的第一个字段是指向虚函数表的指针。这意味着在x86-64/Linux上每个对象8个字节。每个对象(假设单一继承)都有一个虚函数表指针,与虚函数的编号或代码大小无关功能。
如果在多个超类中有多个虚方法的多重(可能是虚)继承,则每个实例需要几个虚表指针。
因此,对于您的Foo
示例,没有virtual
函数(并且没有包含其中一些的超类),因此Foo
的实例不包含虚表指针。
如果向Foo
添加一个(或数百个)虚函数(那么你应该有一个虚析构函数,参见c++中的三规则),每个实例将有一个虚表指针。
如果您希望行为特定于实例(因此实例a
和b
可能具有不同的行为)而不使用类机制,则需要一些成员函数指针(在c++ 03中)或(在c++ 11中)一些std::function
(可能是匿名闭包)。当然,它们在任何情况下都需要空间。
顺便说一句,要知道某些类型或类的大小,请使用sizeof
....
方法存在于程序中的每个类,但不是每个对象。试着读一些关于c++的好书来了解这么简单的语言知识。
- C++代码以测试另一个.cpp如果可以编译它
- C++方法实现:是否可以避免每次都键入类名?
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 我可以避免通过time_t打印时间点吗
- 有什么技巧可以避免在模板类中使用"typename"关键字吗
- 在这种情况下,我可以避免使用带有主体的纯虚函数吗?
- 是否可以避免将参数复制到 lambda 函数?
- 是否有一种方法可以避免标头文件中使用的constexpr函数输入全局范围,而无需额外的名称空间
- 如果可以将其放在私有中,为什么要使用静态常量(int/string/.)?
- 如果BOOL仅从false到true一次,我可以避免锁定布尔
- 是否有一种方法可以避免在RVALUE和LVALUE参考中创建功能时避免重复的代码
- 在这种情况下是否可以避免使用虚拟方法调用?
- 是否可以避免在前向声明中使用嵌套命名空间?
- 使用GCOV时,是否有一种方法可以避免使用CPP文件中包含的标头文件进行仪器
- 是否可以避免 for 循环来计算矩阵条目
- 在Thrift中,有没有一种方法可以避免生成C++setter
- 我可以避免在std ::变体中明确编写每个结构的构造函数
- 是否可以避免使用lambda中的尾随返回型语法
- 每个对象的实例都在内存中重复方法吗?如果是这样,这是可以避免的吗?
- 如果分配器提供realloc语义,std::vector是否可以避免复制