Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:结构中的函数是否随结构一起复制?_C++_Function_Struct - Fatal编程技术网

C++ C++;:结构中的函数是否随结构一起复制?

C++ C++;:结构中的函数是否随结构一起复制?,c++,function,struct,C++,Function,Struct,在结构(或类)中,我知道我可以添加一个函数,然后稍后调用它 struct状态{ int turnsLeft; void nextTurn(){ 特恩斯勒夫特--; } }; 国家s1{1}; 国家s2{2}; s1.nextTurn(); 我的问题是,这些函数与结构占用的空间有什么关系?我知道int是4个字节,所以创建s1和s2至少需要4*2=8个字节。但是,每次我创建新结构时是否会创建此函数的新副本,或者无论我创建了多少不同的状态函数,是否只创建并共享一个函数副本?如果每次都复制函数,我如何

在结构(或类)中,我知道我可以添加一个函数,然后稍后调用它

struct状态{
int turnsLeft;
void nextTurn(){
特恩斯勒夫特--;
}
};
国家s1{1};
国家s2{2};
s1.nextTurn();

我的问题是,这些函数与结构占用的空间有什么关系?我知道int是4个字节,所以创建s1和s2至少需要4*2=8个字节。但是,每次我创建新结构时是否会创建此函数的新副本,或者无论我创建了多少不同的
状态
函数,是否只创建并共享一个函数副本?如果每次都复制函数,我如何编写代码以便只复制一个函数?静态函数不能很自然地工作,因为我想在修改
turnsLeft
时访问
this
,我想我需要从一个免责声明开始:我下面所说的适用于所有已知的实现。从理论上讲,有些人可能会有不同的看法(但在这种情况下,这几乎不可能,甚至不值得考虑作为一种智力练习)

成员函数只会以一种方式影响类的大小:如果类至少包含一个虚拟函数,则类的大小将增加一个指针(通常称为vtable指针)的大小。即使该类不直接定义任何虚拟函数,但如果它继承自至少在虚拟函数上声明的基类,则该类将具有该类的vtable指针。如果它从多个基类继承,通常会为每个基类包含一个vtable指针,该基类至少声明一个虚拟函数。在某些特定情况下,使用
virtual
继承可以减少这种情况

但是不,类的对象通常不“包含”该类函数的实际副本,因此正常成员函数的大小、复杂性或数量不会影响复制该类对象所需的大小或时间。虚拟函数可能会有一些影响,但它通常仍然非常小


成员函数确实会影响另一件事:非静态成员函数可以访问调用它们的对象中的数据。在成员函数内部,指向该对象的指针可见为
this
。在大多数实现中,即使它不是一个可见的参数,
实际上是作为参数传递的,因此如果查看生成的代码,它将包含一条或两条指令,以便在调用之前将
加载到某个已知位置。但这只会影响调用成员函数的代码的大小,而不会影响该类对象的大小。

我不知道有哪种编译器会将函数存储为结构本身的一部分-它们几乎总是存储的elsewhere@3Dave“类的每个实例都包含一个VMT”不,它们不包含。只有多态类才有虚拟表。@3只有具有
virtual
方法的类才有“虚拟方法表”。大多数类没有VMT。首先,只有虚拟函数会导致VMT在大多数实现中存在。其次,虚拟函数调用开销是真实存在的,而不仅仅是纳秒级的问题。@Tumbweed53是的,它是真实存在的,而不仅仅是纳秒级的问题。这也是当你试图从循环中吸取最后几飞秒时,你唯一担心的事情。iOS应用程序开发者永远不会担心VMT当我们需要添加这样的免责声明时,这是一个悲伤的世界。比如,我的光学模拟器解释了Ex、Ey、Ez、Hx、Hy和Hz,但谁知道呢:明天我们可能会发现自己有一个新的领域或新的维度。写得很好,回答很有帮助。@3Dave:事实上,我认为它有一些优点。它需要的理由是C++是一个开放的标准,任何人都可以以任何方式实现它,只要它们满足可见行为的要求。在未来的一些系统中,在对象中包含成员函数的代码几乎不可能有意义,尽管我们现在觉得这很可笑。但即使它仍然是疯狂的,人们做他们认为合适的事情的自由仍然是有价值的。我理解免责声明及其原因。但是,如果我们为edge案例而不是一般案例添加免责声明,那不是很好吗?(前ARM员工工程师,现在是其他地方的GPU人员。我明白你的意思并同意。)可以说,由于标准布局、通用初始序列等原因,不可能为成员函数使用内存。