Отношение к классам как к объектам первого класса

StackOverflow https://stackoverflow.com/questions/605067

Вопрос

Я читал книгу GoF, и в начале раздела о прототипе я прочитал следующее:

Это преимущество относится в первую очередь к языкам, таким как C ++, которые не рассматривают классы как объекты первого класса.

Я никогда не использовал C ++, но я довольно хорошо разбираюсь в OO-программировании, и все же для меня это не имеет никакого смысла.Может ли кто-нибудь поподробнее рассказать об этом (я использовал \use:C, Python, Java, SQL, если это поможет.)

Это было полезно?

Решение

Чтобы класс был объектом первого класса, язык должен поддерживать выполнение таких действий, как разрешение функциям принимать классы (не экземпляры) в качестве параметров, возможность хранить классы в контейнерах и возможность возвращать классы из функций.

В качестве примера языка с первоклассными классами рассмотрим Java.Любой объект является экземпляром своего класса.Этот класс сам по себе является экземпляром java.lang.Класс.

Другие советы

Для всех остальных, вот полная цитата:

"Уменьшено разделение на подклассы.Фабричный метод (107) часто создает иерархию классов Creator, которая параллельна иерархии классов product.Прототип Шаблон позволяет вам клонировать прототип вместо того, чтобы запрашивать фабричный метод для создания нового объекта.Следовательно, вы не нужна иерархия классов Творца вообще.Это преимущество относится в первую очередь к языкам, таким как C ++, которые не рассматривают классы как объекты первого класса.Языки, которые это делают, такие как Smalltalk и Objective C, получают меньше преимуществ, поскольку вы всегда можете использовать класс object в качестве создателя.Объекты класса в этих языках уже действуют как прототипы ". - GoF, стр. 120.

Как Стив говорит об этом,

Я нашел это тонким настолько, насколько кто-то мог бы понять это как подразумевающее что / экземпляры / классов не рассматриваются как объекты первого класса в C ++.Если бы появились те же слова , которые использовал GoF в менее формальной обстановке, они могут хорошо иметь целью /экземпляров/ а чем занятия.Различие может не показаться / вам / тонким./Я/, однако, должен был немного подумать.

Я действительно считаю, что это различие важно.Если я не ошибаюсь, там никаких требований не компилируется в C++ программа сохранить артефакт, с помощью которых класс, от которого объект создан может быть восстановлен.IOW, если использовать терминологию Java, то нет /Класс/ объект.

В Java каждый класс сам по себе является объектом, производным от java.lang.Class, который позволяет вам получать доступ к информации об этом классе, его методах и т.д.изнутри программы.C ++ - это не так;классы (в отличие от их объектов) на самом деле недоступны во время выполнения.Существует средство под названием RTTI (информация о типе во время выполнения), которое позволяет вам выполнять некоторые действия в этом направлении, но оно довольно ограничено и, я полагаю, имеет издержки производительности.

Вы использовали python, который является языком с первоклассными классами.Вы можете передать класс функции, сохранить его в списке и т.д.В приведенном ниже примере функция new_instance() возвращает новый экземпляр класса, которому она передается.

class Klass1:
    pass

class Klass2:
    pass

def new_instance(k):
    return k()

instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)

print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__

Программы на C # и Java могут знать о своих собственных классах, потому что и те, и другие .Среды выполнения NET и Java обеспечивают отражение, что, в общем, позволяет программе иметь информацию о своей собственной структуре (как в .в NET, так и в Java эта структура представлена в терминах классов).

Вы никоим образом не можете позволить себе размышления, не полагаясь на среду выполнения, потому что программа не может осознавать себя сама по себе *.Но если выполнением вашей программы управляет среда выполнения, то программа может получать информацию о себе из среды выполнения.Поскольку C ++ компилируется в собственный, неуправляемый код, вы никак не можете позволить себе отражение в C ++ **.

...

* Что ж, нет причин, по которым программа не могла бы прочитать свой собственный машинный код и "попытаться сделать выводы" о самой себе.Но я думаю, что это то, чего никто не хотел бы делать.

** Не совсем точный.Используя ужасные взломы на основе макросов, вы можете добиться чего-то похожего на отражение, если ваша иерархия классов имеет один корень.Примером этого является MFC.

Шаблонное метапрограммирование предложило C ++ больше способов играть с классами, но, честно говоря, я не думаю, что текущая система допускает полный спектр операций, которые люди могут захотеть выполнить (в основном, нет стандартного способа обнаружить все методы, доступные классу или объекту).Это не оплошность, это сделано намеренно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top