2016-11-03 3 views
0

Я пытаюсь присвоить уникальное значение членам const static unsigned int, не задумываясь о том, чтобы сами присваивать правильные значения (предотвращая человеческие ошибки). Я создал минимальное решение для static unsigned int, но я бы очень хотел использовать const, потому что он быстрее (и аккуратно).Как назначить const static с инкрементным макросом?

Это то, что я придумал:

// cat.h 
#define ANIMAL_INDEX 0 
#define GET_ANIMAL_INDEX (ANIMAL_INDEX (ANIMAL_INDEX + 1)) 

class Cat 
{ 
protected: 
    Cat(){} 
public: 
    const static unsigned int lynx = GET_ANIMAL_INDEX; // 0 
    const static unsigned int tiger = GET_ANIMAL_INDEX; // 1 
}; 

Это просто пример, но представьте себе, что я бы как 1000 животных или что-то.

Возможно ли создать макрос, который увеличивается каждый раз, когда он используется для назначения, или мне нужно создать скрипт, который генерирует cat.h?

+0

Это действительно то, что [* перечислений *] (http://en.cppreference.com/w/cpp/language/enum) для. –

+0

@Someprogrammerdude Я хочу создать сложное перечисление, способное наследовать. Класс dog.h имел бы константы, которые не имеют того же значения, что и константы в классе cat.h. Таким образом, я мог бы назвать Animal :: lynx и Animal :: corgi без конфликтов значений. – oddRaven

+0

Какое у вас есть решение? Это не может быть код в вашем вопросе, так как этот код ошибочен. Требование вашего комментария важно и должно быть в самом вопросе. – rici

ответ

0

Если вы счастливы, чтобы переместить определение ваших констант вне их класса, то простая статическая функция реализации на основе решает проблему:

class UniqueIndex 
{ 
public: 
    static int getNext() 
    { 
     static int theIndex = 0; 
     return theIndex++; 
    } 
}; 

class Cat 
{ 
protected: 
    Cat(){} 
public: 
    const static unsigned int lynx; 
    const static unsigned int tiger; 
}; 

const unsigned int Cat::lynx = UniqueIndex::getNext(); 
const unsigned int Cat::tiger = UniqueIndex::getNext(); 

int main() 
{ 
    std::cout << Cat::lynx << ' ' << Cat::tiger << std::endl; //output: 0 1 
    return 0; 
} 
0

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

Добавить абстракцию вокруг «указателя» и позволить этому обрабатывать счет.
Тогда ваши члены могут быть экземплярами этого «типа индексирования».

Что-то вроде этого:

class Index 
{ 
public: 
    Index() : idx(next()) {} 
    Index(const Index&) = delete; 
    Index& operator=(const Index&) = delete; 
    operator int() const { return idx; } 
private: 
    const int idx; 
    // Avoid the "static initialization order fiasco". 
    static int next() { static int i = 0; return i++;} 
}; 

struct A 
{ 
    const static Index idx; 
}; 

const Index A::idx; 

struct B 
{ 
    const static Index idx; 
    const static Index idx2; 
}; 

const Index B::idx; 
const Index B::idx2; 

int main() 
{ 
    cout << A::idx << " " << B::idx << " " << B::idx2 << endl; 
} 
Смежные вопросы