Что такое "печатать модели"? - PullRequest
1 голос
/ 25 октября 2009

В Beyond Java (раздел 2.2.9) Брут Тейт утверждает, что «модель типирования» является одной из проблем C ++. Что это значит?

Ответы [ 2 ]

3 голосов
/ 25 октября 2009

Он имеет в виду, что объекты в C ++ по своей природе не имеют типов. Хотя вы можете написать

struct Dog {
    char* name;
    int breed;
};

Dog ralph("Ralph", POODLE);

на самом деле ralph не имеет типа; это всего лишь куча битов, и процессор не обращает внимания на тот факт, что вы называете эту коллекцию битов Dog. Например, допустимо следующее:

struct Cat {
    int color;
    char* country_of_origin;
};

Cat ralph_is_that_you = * (Cat*) &ralph;

С удивлением наблюдайте, как профессор С выполняет трансвидовые мутации между Dog с и Cat с! Дело в том, что, поскольку ralph - это просто последовательность битов, вы можете просто утверждать, что эта последовательность битов действительно является Cat, и ничто не пойдет не так ... за исключением того, что цвет "Cat" было бы случайным большим целым числом, и вам лучше не пытаться читать его страну происхождения. Основная проблема заключается в том, что, хотя переменная (например, имя, а не объект, который она представляет) имеет тип, базовый объект - нет.

Сравните это с JAVA, где не только типы, но и объекты имеют внутренние типы. Это может быть отчасти связано с тем, что нет указателей и, следовательно, нет доступа к памяти, но тем не менее существует тот факт, что если вы приведете Dog к Object, вы не сможете вернуть его обратно к Cat, потому что объект знает, что в глубине души это на самом деле Dog, а не Cat.

Слабая типизация, присутствующая в C ++, довольно пагубна, поскольку делает статические проверки типов компилятором практически бесполезными, если вы хотите действительно защитить приложение от злоупотреблений, а также затрудняет написание защищенного и надежного программного обеспечения. Например, вам нужно быть очень осторожным, когда вы получаете доступ к «указателю», потому что это может быть любой случайный битовый шаблон.

РЕДАКТИРОВАТЬ 1: Комментарии были очень хорошие моменты, и я хотел бы добавить их здесь.

kts указывает на то, что JAVA от Sun действительно имеет указатели, если вы посмотрите достаточно глубоко. Спасибо! Я не знал, и это довольно круто. Однако фундаментальный момент заключается в том, что объекты JAVA имеют тип , а типы C - нет. Да, вы можете обойти это, но это то же самое, что разница между отказом от рассылки и отказом от рассылки спама: да, вы можете злоупотреблять указателями JAVA, но по умолчанию недопустимо злоупотребление. Вы должны были бы согласиться.

martin-york указывает на то, что приведенный мной пример является чисто C-феноменом. Это правда, но

  1. C ++ в основном содержит C в качестве подмножества (различия обычно слишком малы, чтобы перечислять).
  2. C ++ включает reinterpret_cast<T> специально для того, чтобы разрешать подобные хаки.
  3. То, что он обескуражен, не означает, что он не распространен и не опасен. По сути, даже если у JAVA есть дополнительные указатели (как я их назову), дело в том, что человек, использующий их, вероятно, задумался о последствиях. Кастинги Си настолько просты, что иногда они делаются без раздумий (Цитируя Страуструпа, «Но новый синтаксис был сделан намеренно уродливым, потому что приведение все еще уродливо и часто небезопасно».). Есть также тот факт, что работа, необходимая для обхода системы типов JAVA, намного больше, чем то, что могло бы сделать для умного взлома, в то время как обойти систему типов C (и, да, систему типов C ++) достаточно легко, что я видел это сделано только для небольшого повышения производительности.

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

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

0 голосов
/ 25 октября 2009

Что трудно набрать код C ++. : -Р

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

...