Лучший подход для определения константы (используемый в константном выражении) в классе?

Попробуйте это:

class AcquisitionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Acquisitions
        fields = ('id', 'implant', 'beg_acq', 'duration_acq')

class RawDatasSerializer(serializers.ModelSerializer):
    class Meta:
        model = RawDatas
        fields = ('id', 'data_type', 'sampling_freq', 'bin_file', 'acq')

    def create(self, validated_data):
        acq_data = validated_data.pop('acq')
        acq = Acquisitions.objects.filter(id=acq_data.get('id')).first()

        if not acq:
            acq = AcquisitionSerializer.create(AcquisitionSerializer(), **acq_data)

        rawdata = RawDatas.objects.create(acq=acq, **validated_data)

        return rawdata
6
задан aJ. 6 April 2009 в 11:07
поделиться

7 ответов

Это всегда лучше для целей обслуживания ограничить объем любого имени (быть этим функция, переменная или постоянная) так же как возможным. Таким образом, я предложил бы также

static const int BUFFER_LENGTH = 12;

или

enum { BUFFER_LENGTH = 12 };

в определении класса.

Нет большого преимущества для первого, за исключением того, что можно явно управлять типом. enum причины C++ для выбора неуказанного интеграла, "лежащего в основе типа" для Вас - это могло быть столь же маленьким как char если Ваше перечисление содержит только маленькие значения, хотя опытным путем, большинство компиляторов по умолчанию будет использовать int.

9
ответ дан 8 December 2019 в 04:10
поделиться

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

Если бы значение константы запутано с классом, я определил бы его там. Затем у Вас все еще есть два варианта:

 class WithConst {
 public:

     // 1. as a const static member variable
     static const int sc_nNumber = 100; // I can initialize here for
                                        // integral-types only

     // 2. as a static member function - possibly inlined.
     static int sf_nNumber() { return 100; }
 };

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

10
ответ дан 8 December 2019 в 04:10
поделиться

Статическая членская переменная константы является лучшей - это кратко, решает проблему полностью и гарантирует, что никакие конфликты не произойдут с другими подобными классами (который довольно возможен с определением препроцессора или глобальной константой). Я предлагаю, чтобы Вы объявили это в CamelCase скорее, что во всех прописных буквах с undescores так, чтобы это не смотрело как что-то специальное, но как нормальный участник класса, который это действительно.

3
ответ дан 8 December 2019 в 04:10
поделиться

Я читал в "Размышлении в C++", что "перечислимый взлом" использовался в прошлом, потому что некоторые компиляторы не поддерживали "статическую константу" участники класса:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_023.html

Таким образом, если Вы используете старинный компилятор или хотите поддерживать их, используют перечислимый взлом. (Я понятия не имею, Какого возраста они должны быть для не поддержки статической константы),

2
ответ дан 8 December 2019 в 04:10
поделиться

Используя константу интервал может быть менее эффективным, чем использование перечисления, ниже является программой, которая демонстрирует это. Скомпилированный с Metrowerks CodeWarrior 8.x для Windows, это показывает, что объект класса, который определяет константу как интервал константы, берет 4 байта памяти больше, чем подобный класс, который определяет эту константу как перечисление:

#include <stdio.h>
#include <stdlib.h>

class foo {
    enum { MY_CONST = 1 };
    int x;
    public:
    foo();
};
class bar {
    const int MY_CONST;
    int x;
    public:
    bar();
};

int main() {
    printf( "%u %u\n", sizeof( foo), sizeof( bar));
    return EXIT_SUCCESS;
}

Это производит: "4 8"

Конструкторы были добавлены для предотвращения агрессивной оптимизации компилятором. Поскольку программа не создает объекты этих типов, конструкторы не должны быть на самом деле определены в модуле раздельной компиляции. То же верно для интервала константы

1
ответ дан 8 December 2019 в 04:10
поделиться

Я не уверен, являются ли они абсолютно взаимозаменяемыми в этом конкретном случае. Так как Вы основываете размер участника массива на константе, я полагаю, что это должно быть перечисляемое значение. У меня нет времени для поиска его в Стандарте, но я был бы удивлен, можно ли использовать int участник как размер массива, даже если это static const так как фактическое значение не могло бы быть видимо в заголовке.

// === in myclass.h
class MyClass {
public:
    static const int MY_SIZE;
private:
    int ary[MY_SIZE];
};

// === in myclass.cpp
/*static*/ const int MyClass::MY_SIZE = 10;

// === in otherclass.cpp
void OtherClass::operation(MyClass& obj) {
    std::cout << "Sizeof(MyClass) = " << sizeof(obj) << std::endl;
}

Я не думаю, что компилятор может скомпилировать otherclass.cpp не уже скомпилировав myclass.cpp.

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

Править

Я просто смотрел на Стандарт, пока я жевал далеко на ланче (Спасибо за пошаговое перемещение David)

Целочисленное константное выражение может включить только литералы (2.13), перечислители, const переменные или статические элементы данных интеграла или перечисляемых типов, инициализированных с константными выражениями (8.5), не введите шаблонные параметры интеграла или перечисляемых типов, и sizeof выражения.

Это похоже на константу и перечислимый, оба будут работать при условии, что Вы обеспечиваете постоянный инициализатор в объявлении (или то определение?).

1
ответ дан 8 December 2019 в 04:10
поделиться

In reading previous posts i noticed that no one mentioned an "enum in a namespace" trick. If you like enums because you are working on an older compiler (I've had such experience on VxWorks/Tornado embedded programming platform), then listen up: you can avoid naming collisions by placing enum inside a namespace or (if namespaces aren't supported either) inside a class.

0
ответ дан 8 December 2019 в 04:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: