Являются ли необработанные указатели C ++ первоклассными объектами? - PullRequest
8 голосов
/ 23 апреля 2010

Согласно Википедии :

Объект является первоклассным, когда он:

  • может храниться в переменных и структурах данных
  • может быть передано в качестве параметра подпрограмме
  • может быть возвращено как результат подпрограммы
  • может быть построен во время выполнения
  • имеет внутреннюю идентичность (независимо от имени)

Кто-то однажды сказал мне, что необработанные указатели не являются объектами первого класса, а умные указатели, такие как std :: auto_ptr, являются. Но мне кажется, что необработанный указатель (на объект или функцию) в C ++ удовлетворяет указанным выше условиям, чтобы квалифицировать его как объект первого класса. Я что-то пропустил?

Ответы [ 5 ]

3 голосов
/ 23 апреля 2010

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

Хорошим примером языка, в котором все объекты первого класса, является Python. В Python все имеет какой-то тип, связанный с ним, его можно рассматривать как объект, он может иметь члены, функции и т. Д. В качестве крайнего примера, даже функции в Python являются объектами, которые просто содержат код и оказываются вызываемыми ; на самом деле, если вы попытаетесь вызвать функцию, используя функцию-член __call__ (которая схожа с перегрузкой operator () в C ++ и которую могут предоставить другие не функциональные объекты), обычная функция в результате вернет обертку функции ( чтобы вам не приходилось рассматривать функции как особый случай). Вы даже можете добавлять членов к функциям, как если бы вы использовали другие объекты. Вот пример такой вещи:

>>> def f(x):
...     return x;
... 
>>> func = f;
>>> print f.__class__

>>> print f(5)
5
>>> print f.__call__(5)
5
>>> f.myOwnMember = "Hello world!"
>>> print f.myOwnMember
Hello world!

Я извиняюсь за Python в посте C ++, но без контраста трудно объяснить концепцию.

2 голосов
/ 23 апреля 2010

Статья в Википедии - это дерьмо (на этот раз я согласен с «необходимостью цитирования»), но вы ничего не упускаете: согласно определению Википедии, а также согласно любому здравому определению, необработанные указатели C ++ являются первыми. объекты класса .

Если кто-то захочет помочь мне с поиском в Google Scholar, мне бы очень хотелось, чтобы статья в Википедии была исправлена. Я являюсь экспертом в своей области, но я также очень занят - мне бы хотелось, чтобы с ним работал партнер.

1 голос
/ 23 апреля 2010

На самом деле оба - «Указатели являются FCO» и «Указатели не являются FCO» - верныНам нужно принять заявления в соответствующем контексте.(FCO - Объект первого класса)

Когда мы говорим о «указателе» в C ++, мы говорим о типе данных, который хранит адрес некоторых других данных.Теперь, будет ли это FCO или нет, действительно зависит от того, как мы планируем его использовать.К сожалению, эта семантика использования не является встроенной для указателей в C ++.

Если мы используем указатели просто для «указания» на данные, это будет отвечать требованиям FCO.Однако, если мы используем указатель для «хранения» данных, он больше не может рассматриваться как FCO, так как его семантика копирования и назначения не работает.Такие указатели «обработки ресурсов» (или более прямо называемые «сырые указатели») представляют наш интерес в контексте исследования Smart Pointer.Это не FCO, а соответствующие умные указатели.Напротив, простые указатели отслеживания продолжали бы соответствовать требованиям для FCO.

Следующий абзац из книги «Современный дизайн C ++» прекрасно разъясняет суть.

Я цитирую из главы об умных указателях:

Объект с семантикой значенияэто объект, который вы можете скопировать и назначить.Тип int является идеальным примером первоклассного объекта.Вы можете свободно создавать, копировать и изменять целочисленные значения.Указатель, который вы используете для итерации в буфере, также имеет семантику значений - вы инициализируете его так, чтобы он указывал на начало буфера, и увеличиваете его, пока не достигнете конца.Попутно вы можете скопировать его значение в другие переменные для хранения временных результатов.

С указателями, которые содержат значения, выделенные с помощью new, история, однако, сильно отличается.Как только вы написали

Widget * p = новый виджет;переменная p не только указывает, но и владеет памятью, выделенной для объекта Widget.Это потому, что позже вы должны выполнить delete p, чтобы убедиться, что объект Widget уничтожен и его память освобождена.Если в строке после только что показанной строки вы пишете

p = 0;// присваивая что-то еще p, вы теряете право собственности на объект, на который ранее указывал p, и у вас совсем нет шансов снова его захватить.У вас есть утечка ресурсов, и утечки ресурсов никогда не помогают.

Надеюсь, это прояснится.

1 голос
/ 23 апреля 2010

Как прокомментировал Майк, здесь, кажется, есть некоторая путаница со словом «Объект». Ваш друг, кажется, путает объекты, как в «объектах первого класса», и объекты как «экземпляры классов C ++», две совершенно разные вещи, где слово «объект» используется для двух совершенно разных вещей.

В объектно-ориентированном программировании слово Object используется для обозначения некоторой структуры данных, собирающей поля данных, и методов для их манипулирования. С C ++ вы определяете их в классах, получаете наследование и т. Д.

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

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

1 голос
/ 23 апреля 2010

С вики :

В вычислительной технике - первоклассный объект (также стоимость, лицо и гражданин), в контекст конкретного язык программирования, является сущностью который может быть передан в качестве параметра, вернулся из подпрограммы, или присваивается в переменную. 1 В информатика термин овеществление используется при обращении к процессу (техника, механизм) изготовления что-то первоклассное объект. [цитата нужна]

Я включил всю запись в wiki-pedia для контекста. Согласно этому определению - сущности, которую можно передать в качестве параметра - указатель C ++ будет объектом первого класса.

Дополнительные ссылки, поддерживающие аргумент: catalysoft Wapedia

reification : ссылка на процесс (технику, механизм) создания чего-то первоклассного объекта

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