繁体   English   中英

全局与成员函数

[英]Global vs. Member functions

我最近一直在玩c ++,想知道为什么会有这么多的全局函数。 然后我开始考虑用c#编程以及如何存储成员函数,所以我想我的问题是我是否有:

public class Foo {
    public void Bar() { ... }
}

然后我做了一些愚蠢的事情,例如在列表中添加1,000,000 Foo 这是否意味着我有1,000,000个Foo对象坐在内存中,每个对象都有自己的Bar()函数? 还是更聪明的事情发生了?

谢谢。

不,只有一个实例。 一个类的所有实例都指向一个对象,该对象包含所有带有隐式第一个参数的实例方法,这些参数被亲切地称为this 在实例上调用实例方法时,该实例的this指针将作为第一个参数传递给该方法。 这就是方法知道该实例的所有实例字段和属性的方式。

有关详细信息,请参见通过C#进行CLR

当然,这会因virtual方法而变得复杂。 通过C#进行CLR将为您阐明区别,如果您对此主题感兴趣, 强烈建议您这样做。 无论哪种方式,每个实例方法仍然只有一个实例。 问题在于如何解决这些方法。

实例方法只是带有隐藏this参数的static方法。

virtual方法要复杂一些)

在C ++中,成员函数通常不需要任何按对象存储(在下一段中将讨论异常- virtual函数)。 通常,在使用函数的每个点,编译器都会生成特定于CPU的机器代码以直接调用该函数,对于内联函数,可以避免调用,并且可以将函数的影响最佳地集成到调用者的代码中(可以〜小功能(例如仅读取或写入一个成员变量的“ getter和setter”)的速度提高了10倍。

对于那些具有一个或多个虚拟函数的类,每个对象将具有一个额外的指针,该指针指向每个类的函数指针表和其他信息。 因此,每个对象都以指针的大小增长-通常为4或8个字节。

解决您的原始观察结果:C ++具有更多的非成员函数(通常在std名称空间中),但是无论如何,名称空间在此目的上都比类更好。 实际上,名称空间实际上是可跨越许多“物理”头文件的“静态”功能和数据的逻辑接口。 为什么要考虑与物理文件相关的考虑因素而损害程序的逻辑API,这些因素对构建时间,文件修改时间戳记触发的make工具等都有影响? 在名称空间位于一个标头中的普通情况下,C ++可以使用类或结构来限制相同的声明,但这不太方便,因为它阻止使用名称空间别名, using名称空间和Koenig查找来隐式搜索与功能匹配的名称空间参数的名称空间-在每个使用点强制使用非常明确的前缀。 它还给人一种错误的印象,即用户打算从内容中实例化一个对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM