Обработка классов как первоклассных объектов - PullRequest
5 голосов
/ 03 марта 2009

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

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

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

Ответы [ 6 ]

8 голосов
/ 03 марта 2009

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

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

7 голосов
/ 03 марта 2009

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

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

Как Стив говорит: ,

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

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

4 голосов
/ 03 марта 2009

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

2 голосов
/ 03 марта 2009

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

2 голосов
/ 03 марта 2009

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

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

...

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

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

2 голосов
/ 03 марта 2009

Вы использовали 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__
...