2009-06-04 3 views
10

Я видел код как и часто следуя в некотором коде C++ Я смотрю на:Какова цель наложения класса на C++?

typedef class SomeClass SomeClass; 

Я проковылял, как к тому, что это на самом деле достигает. Похоже, это ничего не изменит. Что делать typedef s нравится это делать? И если это что-то полезно, стоит ли прилагать дополнительные усилия?

+4

Возможно, вы должны спросить этого человека? а не просить всех, кроме этого человека. – DevinB

+0

Я хотел получить консенсус относительно того, действительно ли это того стоит, а не объяснения одного человека. –

+0

И парень на самом деле был неправ. «non-tag скрывает имя тега в C++» - ни true в C, ни true в C++. Для некоторого вдохновения прочитайте этот отчет о дефектах http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407 –

ответ

7

См. Предыдущий ответ на соответствующий вопрос. Это длинная цитата из статьи Дэн Сакс объясняет, что этот вопрос так ясно, как все, что я пришел через:

Difference between 'struct' and 'typedef struct' in C++?

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

Это дешевая страховка - это нулевая стоимость во время выполнения или в кодовом пространстве (единственная стоимость - это несколько байтов в исходном файле), но защита, которую вы получаете, настолько мала, что редко можно увидеть, как кто-то ее использует последовательно. У меня есть «новый класс», который включает в себя typedef, но если я на самом деле код класса с нуля без использования фрагмента, я почти никогда не беспокоюсь (или не помню?), Чтобы добавить typedef.

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

.

Я попросил пример того, как не имеющее имя класса 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 и кланом нет конфликта имен ss foo.

Однако, если вы включите «typedef class foo foo;», вы получите ошибку времени компиляции вместо молчаливой разницы в поведении.

+0

Вы должны это сделать много вещей, чтобы это произошло, что я соблазн сказать, что вы этого заслуживаете! Номер один будет предоставлять преобразования, вместо использования названных функций (всегда нет-нет, IMHO). – 2009-06-05 08:32:47

+2

Операторы преобразования могут быть не-нет, но они совсем не редкость. Во всяком случае, я не буду утверждать, что «так много вещей должно идти не так». Как я уже сказал, это не то, что я настаиваю на своем или чужом коде. Но я хотел объяснить, почему он находится в коде OP (это был вопрос в конце концов), и указать, что typedef не требует затрат и не вызывает проблем. Фактически, это заставляет компиляторы действовать немного больше, как люди ожидают - хотя я был удивлен поведением некоторых компиляторов к фрагменту Адама. Я думаю, что документ, связанный с litb, является образовательным в этом отношении. –

+0

Это действительно интересно; ответы, которые я получил на этот вопрос, радуют меня, я задал этот вопрос здесь. –

0

Похоже, что комментарий пытается сказать, что typedef делает символ SomeClass глобальным таким образом, чтобы никто не мог объявить локальный объект с тем же именем, который скрывает оригинальный SomeClass.

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

-2

Я понимаю концепцию разных пространств имен, теги и идентификаторов живут в, но это действительно стоит даже беды набрав его?

No.

+6

(-1) Абсолютно никаких объяснений и аргументов. Я мог так же легко написать «Да». и единственным отличием была бы репутация. – DevinB

+0

Вам не нравится мой ответ (он, в конце концов, изложил рассуждения), напишите свое. –

0

Он смотрит на меня, как ваш коллега, возможно, не полностью закончил C.

В C, если вы объявите struct foo {int a;};, вы не имеете, что вы можете назвать только foo , а скорее struct foo. Поэтому довольно типично typedef struct foo как foo.

Это было изменено на C++, по причинам, которые должны быть достаточно очевидными.

+1

Возможно, но я бы не назвал поведение C «скрытым именем». –

20

Это предотвращает код, как это от компиляции:

class SomeClass { ... }; 
int SomeClass; 

Это совершенно законно C++, хотя это ужасный. Если вы сделаете это, то любые ссылки на голый SomeClass относятся к переменной. Чтобы обратиться к классу, вам нужно явно указать class SomeClass при каждом использовании. Если вы создаете typedef:

class SomeClass { ... }; 
typedef class SomeClass SomeClass; 
int SomeClass; 

Тогда флаги компилятора определение int SomeClass как ошибка, так как она по праву должна быть.

+0

Ваш второй пример компиляции для меня (VC2005). –

+3

Проблема с VC++ тогда - она ​​не должна компилироваться. – 2009-06-04 21:42:27

+0

Интересно, что он работает с одним компилятором, который я использую (а не с MSVC). – Dolphin

0

Либо действительно сломанный компилятор, либо кто-то не знает, что они делают, или так я думаю.

+0

Или кто-то знает что-то, что многие люди не знают ... –

6

Адам дал правильную причину для этого, но в отношении вашего вопроса «Стоит ли проблемы» я бы дал громкую «Нет!».Возможный код проблемы:

class SomeClass { ... }; 
int SomeClass; 

будет пойман, когда немного позже кто-то говорит:

SomeClass sc; 

Правда компилятор будет указывать на «неправильной» линии, но такого рода вещи случаются так редко (Я не думаю, что когда-либо видел его в реальном коде), что он не может оправдать лес почти избыточных typedefs.

+0

Спасибо, что ответили на этот вопрос, вот что я действительно хотел знать. Я никогда не видел, чтобы это делалось раньше, поэтому у меня было ощущение, что это не стоит того. –

+0

Если вы не укажете typedef, вы не всегда можете получить сообщение об ошибке, хотя, по общему признанию, ситуации будут редкими. Функция с тем же именем, что и класс, может скрыть что-то, что в противном случае было бы конструктором класса. –

+0

Не могли бы вы привести пример этого - я не могу представить, как это было бы возможно. – 2009-06-05 07:38:56

Смежные вопросы