Переучивание C ++ и проблема определения типа - PullRequest
0 голосов
/ 02 августа 2010

Итак, прошло 5 или 6 лет с тех пор, как я использовал C ++ для большого проекта, и около полугода с тех пор, как мне в последний раз приходилось иметь дело с небольшими / тривиальными программами C ++ и средой выполнения C ++ в целом. Я решил, что хочу заново выучить язык, прежде всего потому, что он может оказаться очень актуальным для будущего проекта на работе.

Я работал в основном с C и Python, и сейчас я нахожусь в такой ситуации, что мне даже не по себе с синтаксисом цикла for ниже:

for( int i(0); i != n; ++i) {}

хотя я признаю, что это не так сложно расшифровать.

Поскольку я понимаю, что к языку, библиотекам и, конечно же, идиомам, шаблонам и стилям было добавлено много дополнений, я хотел бы узнать ваше мнение о хороших ресурсах, которые актуальны. Я хотел бы избежать учебников, которые используют подход «Это Си с большим количеством дополнений». У меня все еще есть обязательная копия «языка программирования C ++», которую я изучаю, но я, честно говоря, не знаю точно, на чем сосредоточиться дальше. Шаблоны проектирования? Шаблоны и STL / Boost? Что-то еще?

Я открыт для всех предложений!

Кроме того, более конкретный вопрос относительно typedef с. Является ли следующее:

typedef Type& TypeRef;

обычно считается хорошей практикой при предоставлении непрозрачных типов как части API? То есть со значимым именем. Вообще ли это похоже на подход, принятый библиотеками, такими как pthreads или libpcap , и если да, то предпочтительнее ли использовать указатель для той же работы?

Заранее спасибо.

Ответы [ 3 ]

4 голосов
/ 02 августа 2010

Чтобы ответить на ваш конкретный вопрос, typedefs, которые скрывают тот факт, что что-то является указателем или ссылкой, всегда являются плохой идеей - то же самое верно для C. Рассмотрим, например, непрозрачный тип FILE - все же необходимо явно создать FILEуказатели для того, чтобы использовать его.

Что касается книг, см. Полное руководство и список книг C ++ .

3 голосов
/ 02 августа 2010

Мне никогда не нравится определение типов ссылок или указателей.Невозможно эффективно скрыть тот факт, что тип является указателем по сравнению со ссылкой, поскольку они имеют различную семантику вызовов для клиентов, поэтому в моем опыте это только приводит к путанице.

0 голосов
/ 02 августа 2010

Политика typedef, принятая ядром Linux для C, является лучшей.По сути, политика заключается в том, чтобы не использовать typedefs, если вы не создаете абстракцию нового типа.Это полезно в тех случаях, когда низкоуровневые типы различаются в разных архитектурах, но пользователям ядра нужен общий тип.Например, u64 задается конкретный тип, но базовый тип может меняться между сборками или архитектурами.

typedef u64 unsigned long long;

Однако, весьма вероятно, что в C ++ существуют разные идиомы, использующие typedefsэто вполне приемлемо, однако, я бы освоился с C до C ++.

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

Вот ядро ​​Linuxстандарт typedef, взято из http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.33.y.git;a=blob_plain;f=Documentation/CodingStyle;hb=HEAD

  Chapter 5: Typedefs

Пожалуйста, не используйте такие вещи, как "vps_t".

Это ошибка использовать typedef дляструктуры и указатели.Когда вы видите

vps_t a;

в источнике, что это значит?

В отличие от этого, если оно говорит

struct virtual_container * a;

на самом деле вы можете сказать, что такое "a".

Многие думают, что typedefs "помогают читабельности".Не так.Они полезны только для:

(a) полностью непрозрачных объектов (где typedef активно используется, чтобы скрыть , что это за объект).

 Example: "pte_t" etc. opaque objects that you can only access using
 the proper accessor functions.

 NOTE! Opaqueness and "accessor functions" are not good in themselves.
 The reason we have them for things like pte_t etc. is that there
 really is absolutely _zero_ portably accessible information there.

(b) Очистите целочисленные типы, где абстракция помогает избежать путаницы, является ли она "int" или "long".

 u8/u16/u32 are perfectly fine typedefs, although they fit into
 category (d) better than here.

 NOTE! Again - there needs to be a _reason_ for this. If something is
 "unsigned long", then there's no reason to do

typedef unsigned long myflags_t;

 but if there is a clear reason for why it under certain circumstances
 might be an "unsigned int" and under other configurations might be
 "unsigned long", then by all means go ahead and use a typedef.

(c) когда вы используете sparse для буквального создания нового типа для проверки типов.

(d) Новые типы, идентичные стандартным типам C99, в определенных исключительных обстоятельствах.

 Although it would only take a short amount of time for the eyes and
 brain to become accustomed to the standard types like 'uint32_t',
 some people object to their use anyway.

 Therefore, the Linux-specific 'u8/u16/u32/u64' types and their
 signed equivalents which are identical to standard types are
 permitted -- although they are not mandatory in new code of your
 own.

 When editing existing code which already uses one or the other set
 of types, you should conform to the existing choices in that code.

(e) Типы, безопасные для использования в пользовательском пространстве.

 In certain structures which are visible to userspace, we cannot
 require C99 types and cannot use the 'u32' form above. Thus, we
 use __u32 and similar types in all structures which are shared
 with userspace.

Возможно, существуют и другие случаи, но в принципе следует придерживаться правила НИКОГДА никогда не использовать typedef, если вы не можете четкосоответствует одному из этих правил.

Как правило, указатель или структура, имеющая элементы, к которым можно получить прямой доступ, должна никогда не быть typedef.

...