Как я могу сделать набор констант, чтобы улучшить применимость моих методов? - PullRequest
1 голос
/ 15 мая 2009

Я написал метод, который выполняет некоторые графические вычисления. Там вы можете указать начальное направление, например «слева», «справа», «снизу», «сверху».

Теперь я не хочу, чтобы пользователь моего метода передавал запутанные значения, такие как 1, 2, 3 или 4 или даже строки. Ничего подобного. Вместо этого я хотел бы создать константы, такие как:

kFromLeft, kFromRight, kFromTop, kFromBottom

Я видел это в заголовочном файле Apple:

enum CGImageAlphaInfo {
    kCGImageAlphaNone,              
    kCGImageAlphaPremultipliedLast,  
    kCGImageAlphaPremultipliedFirst, 
    kCGImageAlphaLast,               
    kCGImageAlphaFirst,              
    kCGImageAlphaNoneSkipLast,       
    kCGImageAlphaNoneSkipFirst,     
    kCGImageAlphaOnly                
};
typedef enum CGImageAlphaInfo CGImageAlphaInfo;

Пять вещей, которые я здесь не понимаю / которые мне непонятны:

1) Почему точка с запятой отделяет определение от typedef?

2) Почему они повторяют CGImageAlphaInfo как паро?

3) Если бы я поместил что-то подобное в заголовочный файл, я бы сказал в своем методе, что тип параметра - CGImageAlphaInfo (конечно, у меня будет другое имя), верно?

4) Я бы обычно указывал значения для этих констант таким образом? (Пример):

#define kCGImageAlphaNone 100
#define kCGImageAlphaPremultipliedLast 300
#define kCGImageAlphaPremultipliedFirst 900

5) Требуется ли для этих констант устанавливать такие глупые значения? Или я мог бы просто проверить внутри моего метода, какая константа была передана, например

if(paramConst == kCGImageAlphaNone) {...}

Ответы [ 5 ]

6 голосов
/ 15 мая 2009

1) Точка с запятой всегда завершает оператор enum. В этом случае есть два отдельных оператора: один определяет именованное перечисление, другой определяет новый тип.

2) Оператор enum создает новый тип с именем "enum CGImageAlphaInfo". Но вводить это везде неудобно, поэтому используется оператор typedef. Оператор typedef работает так:

typedef <sometype> <newname>;

Итак, enum CGImageAlphaInfo - это старый тип, а CGImageAlphaInfo - это новое имя. Apple использует одно и то же имя для обоих, что немного сбивает с толку, но это действительно лучший способ сделать это.

3) Верно.

4) Вы можете сделать это, но затем вам придется вручную присваивать постоянные значения; с перечислением значения присваиваются автоматически. Основное преимущество заключается в том, что вы получаете некоторую проверку типов, поскольку вы можете использовать тип CGImageAlphaInfo вместо простого int, которому легче было бы присвоить недопустимые значения.

5) Я не уверен, что вы подразумеваете под "глупыми ценностями". Но да, вы всегда должны проверять использование имени в том виде, как вы его описываете, и никогда не использовать какое-либо необработанное значение, такое как «300» или «1».

3 голосов
/ 15 мая 2009

Использование enum вместо определения препроцессора - лучший способ справиться с этим. Например,

typedef enum
{
    FromTop = 0,
    FromBottom = 1,
    FromLeft = 2,
    FromRight = 3
} GraphicsLocation;

Поместите это в файл Constants.h и импортируйте его, где это необходимо. На самом деле вам не нужно включать = 1, = 2 ..., хотя это полезно, если вам нужно указать фактическое числовое значение для использования в другом месте (например, если вы устанавливаете атрибут тега для пункта меню в интерфейсе Builder).

Я всегда объявлял такие перечисления, а не пример Apple, который вы опубликовали выше. Может быть, кто-то более знакомый с c может оставить комментарий, объясняющий разницу.

3 голосов
/ 15 мая 2009

1) Точка с запятой необходима для завершения определения enum.

2) CGImageAlphaInfo - это имя перечисления и имя определенного типа.

3) Верно.

4) Использование #define для констант часто считается архаичным стилем программирования Си. Объявление констант в enum дает статическим анализаторам больше информации, чем в макросах препроцессора.

5) Вы должны использовать символы, а не числовые литералы.

1 голос
/ 15 мая 2009

Вещи, которые вам непонятны:

1) Потому что объявление перечисления отделено от объявления типа. В примере кода программист сначала объявляет перечисление, а затем объявляет новый тип для использования этого перечисления.

2) Возможно, будет проще, если вы посмотрите на него (синтаксически некорректно) в кавычках: typedef "enum CGImageAlphaInfo" CGImageAlphaInfo. Вы определяете тип CGImageAlphaInfo таким же, как enum.

3) Правильно.

4) Ваш метод #define будет работать нормально. По сути, перечисления - это просто еще один способ сделать такое определение констант, но они выполняются вашим набором компиляции, а не тем, что вы выбираете константы для присвоения каждому имени. Каждое значение в перечислении гарантированно будет отличаться от остальных без необходимости проходить и проверять. При необходимости они также проверяются на ошибки.

1 голос
/ 15 мая 2009

enum обозначает Перечисляемый тип .

Это обычное объявление типа со встроенным определением, синтаксически правильное с точкой с запятой в конце.

1006

Тип действительно должен быть CGImageAlphaInfo.

Ну, обычно относительный, в этом случае использование enum для этого вполне нормально.

В Java это можно сделать, проверив равенство параметров символу enum.

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