Какова цель наложения класса на С++?
Я часто видел код, похожий на следующий код кода С++, на который я смотрю:
typedef class SomeClass SomeClass;
Я в тупике по поводу того, чего это реально добивается. Похоже, это ничего не изменит. Что такое typedef
, как это сделать? И если это делает что-то полезное, стоит ли прилагать дополнительные усилия?
Ответы
Ответ 1
См. предыдущий ответ на соответствующий вопрос. Это длинная цитата из статьи Дэн Сакса, которая объясняет эту проблему так же ясно, как и все, что я встречал:
Разница между 'struct' и 'typedef struct' в С++?
Техника может предотвратить фактические проблемы (хотя, по общему признанию, редкие проблемы).
Это дешевая битва - это нулевая стоимость во время выполнения или в кодовом пространстве (единственная стоимость - это несколько байтов в исходном файле), но защита, которую вы получаете, настолько мала, что это необычно, чтобы кто-то использовал ее последовательно, У меня есть "новый класс", который включает в себя typedef, но если я на самом деле кодирую класс с нуля без использования фрагмента, я почти никогда не беспокоюсь (или не помню?), Чтобы добавить typedef.
Итак, я бы сказал, что не согласен с большинством мнений, приведенных здесь, - стоит поместить эти typedefs, но недостаточно, чтобы я никому (включая меня) не жалел о том, чтобы не вставлять их.
Меня попросили привести пример того, как не иметь имя класса typedef'ed может привести к неожиданному поведению - вот пример, снятый более или менее из статьи Сакса:
#include <iostream>
#include <string>
using namespace std;
#if 0 // change to #if 1 to get different behavior
// imagine that this is buried in some header
// and even worse - it gets added to a header
// during maintenance...
string foo()
{
return "function foo... \n";
}
#endif
class foo
{
public:
operator string() {
return "class foo...\n";
}
};
int main()
{
string s = foo();
printf( "%s\n", s.c_str());
return 0;
}
Когда объявление функции становится видимым, поведение программы бесшумно изменяется, потому что между функцией foo
и классом foo
нет конфликта имен.
Однако, если вы включите "typedef class foo foo;
", вы получите ошибку времени компиляции вместо молчаливой разницы в поведении.
Ответ 2
Это предотвращает компиляцию такого кода:
class SomeClass { ... };
int SomeClass;
Это совершенно законный С++, хотя это ужасно. Если вы сделаете это, то любые ссылки на голый SomeClass
относятся к переменной. Чтобы обратиться к классу, вам нужно явно указать class SomeClass
при каждом использовании. Если вы создаете typedef
:
class SomeClass { ... };
typedef class SomeClass SomeClass;
int SomeClass;
Затем компилятор помещает определение int SomeClass
в качестве ошибки, так как это должно быть правильно.
Ответ 3
Адам поставил правильную причину для этого, но в отношении вашего вопроса "Стоит ли проблемы" я бы дал громкую "Нет!". Возможный код проблемы:
class SomeClass { ... };
int SomeClass;
будет пойман, когда немного позже кто-то скажет:
SomeClass sc;
По общему признанию, компилятор укажет на "неправильную" строку, но такая ситуация случается так редко (я не думаю, что когда-либо видел ее в реальном коде), что она не может оправдать лес почти лишнего Определения типов.
Ответ 4
Похоже, что комментарий пытается сказать, что typedef делает символ SomeClass глобальным таким образом, чтобы никто не мог объявить локальный объект с тем же именем, который скрывает оригинальный SomeClass.
Я пробовал это с помощью VC6 (не настоящий компилятор С++, который я знаю, но лучше всего у меня есть ATM), и это, похоже, мало что делает. SomeClass все еще скрывается локальным объявлением с тем же именем. Возможно, он изменяет содержимое сообщения об ошибке для некоторого компилятора, чтобы сделать его более полезным.
Ответ 5
Мне кажется, что ваш коллега, возможно, не закончил полностью C.
В C, если вы объявите struct foo {int a;};
, у вас нет ничего, что вы можете назвать просто foo
, а скорее struct foo
. Поэтому он довольно распространен для typedef struct foo
как foo
.
Это было изменено на С++, по причинам, которые должны быть достаточно очевидными.
Ответ 6
Либо действительно сломанный компилятор, либо кто-то не знает, что они делают, или так я думаю.
Ответ 7
Я понимаю концепцию различные пространства имен, которые содержат теги и идентификаторы живут, но это действительно даже стоит того набрав его?
Нет.