Глобальные и членские функции - PullRequest
1 голос
/ 29 ноября 2010

В последнее время я играл с c ++ и удивлялся, почему было так много глобальных функций.Затем я начал думать о программировании на C # и о том, как хранятся функции-члены, поэтому я предполагаю, что мой вопрос заключается в том, есть ли у меня:* к списку;Означает ли это, что у меня в памяти находится 1 000 000 Foo объектов, каждый со своей функцией Bar ()?Или происходит что-то намного более умное?

Спасибо.

Ответы [ 3 ]

8 голосов
/ 29 ноября 2010

Нет, есть только один экземпляр.Все экземпляры класса указывают на объект, который содержит все методы экземпляра, которые принимают неявный первый параметр, ласково называемый this.Когда вы вызываете метод экземпляра для экземпляра, указатель this для этого экземпляра передается в качестве первого параметра этому методу.Вот как метод знает все поля и свойства экземпляра для этого экземпляра.

Подробнее см. CLR через C # .

Это, конечно, осложняется virtual методов.CLR через C # разъяснит для вас различие и очень рекомендуется , если вы заинтересованы в этом предмете.В любом случае, существует только один экземпляр каждого метода экземпляра.Вопрос только в том, как эти методы решаются.

3 голосов
/ 29 ноября 2010

Метод экземпляра - это просто метод static со скрытым параметром this.

(virtual методы немного сложнее)

1 голос
/ 29 ноября 2010

В C ++ функция-член не обычно не требует хранения для каждого объекта (исключение - virtual функции - обсуждается в следующем параграфе). Обычно в каждой точке, где используется функция, компилятор генерирует машинный код, специфичный для ЦП, для непосредственного вызова этой функции, а для встроенных функций этого вызова можно избежать, и влияние функции может быть оптимально интегрировано в код вызывающего абонента (который может быть ~ В 10 раз быстрее для небольших функций, таких как «методы получения и установки», которые просто читают или записывают одну переменную-член).

Для тех классов, которые имеют одну или несколько виртуальных функций, у каждого объекта будет один дополнительный указатель на таблицу указателей на функции для класса и другую информацию. Таким образом, каждый объект увеличивается на размер указателя - обычно 4 или 8 байт.

Обращаясь к вашему первоначальному наблюдению: C ++ имеет больше функций, не являющихся членами (обычно в пространстве имен std), но пространство имен в любом случае служит этой цели лучше, чем класс. Действительно, пространства имен являются фактически логическими интерфейсами для «статических» функций и данных, которые могут охватывать многие «физические» заголовочные файлы. Почему логический API программы должен быть скомпрометирован соображениями, связанными с физическими файлами и их влиянием на время сборки, инструментами создания триггера изменения времени файла и т. Д.? В тривиальных случаях, когда пространство имен находится в одном заголовке, C ++ может использовать класс или структуру, чтобы охватить те же объявления, но это менее удобно, поскольку предотвращает использование псевдонимов пространства имен, using пространств имен и поиска Кенига для неявного поиска соответствия пространств имен пространство имен аргументов функции - форсирование очень явного префикса в каждой точке использования. Это также создает ложное впечатление, что пользователь предназначен для создания экземпляра объекта из содержимого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...