Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > enum в классе


Автор: Hagrael 22.7.2011, 19:16
Имеется код:
Код

class cPlayer {
    public:
        cPlayer::ePlayerStatus currentStatus;
    private:
        enum ePlayerStatus {STAND = 0, BLOCK = 1};
};

Компилятор ругается. Говорит "ePlayerStatus in class cPlayer does not name a type". Перевести это я могу (вроде smile): "ePlayerStatus в классе cPlayer не обозначает тип" (хотя возможно я даже конкурентноспособнее, чем Google Translate! smile). Но почему выдается такая ошибка? Если я объявляю ePlayerStatus вне класса, то все ОК, а когда заношу внутрь, то все ломается.

Заранее благодарен.

Автор: boostcoder 22.7.2011, 19:21
Код

   
class cPlayer {
   enum ePlayerStatus {STAND = 0, BLOCK = 1};
public:
   ePlayerStatus currentStatus;
};

int main() {
   cPlayer p;
}

http://liveworkspace.org/code/76ff542aa7bf5fbc9485693c50adcf77

Добавлено через 7 минут и 28 секунд
Цитата(Hagrael @  22.7.2011,  19:16 Найти цитируемый пост)
ePlayerStatus in class cPlayer does not name a type

ePlayerStatus в классе cPlayer не является именем типа.

Автор: Hagrael 22.7.2011, 19:36
Спасибо.

Автор: bsa 22.7.2011, 20:28
Hagrael, скажу тебе сразу, что подобное смысла не имеет. Так как пользоваться currentStatus из-вне (а иначе зачем в public) будет очень затруднительно.

Автор: Hagrael 22.7.2011, 20:34
bsa, только что именно это я и заметил smile Не уже ли для этого нужно создавать глобальный enum? Просто будет не очень красиво.

Автор: boostcoder 22.7.2011, 20:53
Код

   
class cPlayer {
public:
   enum ePlayerStatus { STAND = 0, BLOCK = 1 };
   
   ePlayerStatus currentStatus;
};

int main() {
   cPlayer p;
   cPlayer::ePlayerStatus e = cPlayer::STAND;
}

http://liveworkspace.org/code/03eac72912d9894fc1f81cf2290c7094

Добавлено через 10 минут и 44 секунды
Hagrael, объясни, чего хочешь добиться?

Автор: borisbn 22.7.2011, 21:10
шлифовать, так шлифовать smile

Код

class cPlayer {
public:
    enum ePlayerStatus { STAND = 0, BLOCK = 1 };
    ePlayerStatus currentStatus() const {
        return m_currentStatus;
    }
    void setCurrentStatus( const ePlayerStatus & s ) {
        m_currentStatus = s;
    }
private:
    ePlayerStatus m_currentStatus;
};


P.S.  smile 
Цитата(Hagrael @  22.7.2011,  19:16 Найти цитируемый пост)
cPlayer

Цитата(Hagrael @  22.7.2011,  19:16 Найти цитируемый пост)
ePlayerStatus

именование типов - жуть... венгерщиной попахивает smile

Автор: mes 22.7.2011, 23:56
Цитата(borisbn @  22.7.2011,  20:10 Найти цитируемый пост)
шлифовать, так шлифовать 

я бы еще вынес enum наружу, например так :
Код

namespace  PlayerStatus { 
 enum еNum { STAND = 0, BLOCK = 1 };

typedef PlayerStatus::еNum ePlayerStatus;

class cPlayer {
public:
  
  cPlayer () : currentStatus (PlayerStatus::STAND) 
  {}
   
  ePlayerStatus currentStatus;
};



P.S. имена состоящие из всех заглавнных букв "закреплены" за макросами, поэтому с этим стоит быть поосторожней, чтоб не нарваться на необъснимую ошибку.. 

Автор: Alca 23.7.2011, 00:13
Цитата

я бы еще вынес enum наружу

зачем?

Автор: boostcoder 23.7.2011, 00:20
borisbnmes, может просто почитать про "enum class" ;)
например тут: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf

Добавлено @ 00:30
Alca, перешел по ссылке у тебя в подписи, а там внизу страницы есть такое:
user posted image
ну добавь readme. а то реально не понятно что за либа.

Автор: volatile 23.7.2011, 01:22
Цитата(mes @  22.7.2011,  23:56 Найти цитируемый пост)
namespace  PlayerStatus { 
 enum еNum { STAND = 0, BLOCK = 1 };

typedef PlayerStatus::еNum ePlayerStatus;

mes, а какой смысл заключать в namespace, и тут же делать синоним в global scope?
т.е. в чем разница, с этим:
Код

enum ePlayerStatus { STAND = 0, BLOCK = 1 };


Автор: Hagrael 23.7.2011, 07:32
Цитата(borisbn @  22.7.2011,  21:10 Найти цитируемый пост)
именование типов - жуть... венгерщиной попахивает

А вы бы как это оформили, можете показать? (или то, как вы написали, и есть ваш вариант?)

Цитата(boostcoder @  22.7.2011,  20:53 Найти цитируемый пост)
cPlayer::ePlayerStatus e = cPlayer::STAND;

Обращение через cPlayer::... Значит, нельзя присвоить enum классу, а после обращаться к его "вариантам" напрямую (без cPlayer::). Тогда буду делать enum глобальным.

Автор: borisbn 23.7.2011, 09:18
Цитата(Hagrael @  23.7.2011,  07:32 Найти цитируемый пост)
А вы бы как это оформили, можете показать?

Код

class Player {
public:
    enum Status { STAND = 0, BLOCK = 1 };
    Status currentStatus() const {
        return m_currentStatus;
    }
    void setCurrentStatus( const Status & s ) {
        m_currentStatus = s;
    }
private:
    Status m_currentStatus;
};

А чтобы не пересекаться с каким-нибудь другим плеером заключить весь класс в namespace с названием проекта (или ещё какм-нить)

Цитата(Hagrael @  23.7.2011,  07:32 Найти цитируемый пост)
Обращение через cPlayer::... Значит, нельзя присвоить enum классу, а после обращаться к его "вариантам" напрямую (без cPlayer:smile

обращаться можно (см. typedef от mes), но IMHO так ( с Player:: ) будет более читабельно... Сразу понятно о каком статусе идёт речь.

Автор: mes 23.7.2011, 10:34
Цитата(boostcoder @  22.7.2011,  23:20 Найти цитируемый пост)
 может просто почитать про "enum class" ;)

Вы думаете мы не в курсе ? ;) или считаете, что новичков с ходу надо грузить новым стандартом ? 

Цитата(Alca @  22.7.2011,  23:13 Найти цитируемый пост)
Цитата

я бы еще вынес enum наружу

зачем? 

чтоб не нагружать класс плеера тем, что к нему относится косвенно.. 

Цитата(volatile @  23.7.2011,  00:22 Найти цитируемый пост)
 а какой смысл заключать в namespace, и тут же делать синоним в global scope?
т.е. в чем разница, с этим:
Код

enum ePlayerStatus { STAND = 0, BLOCK = 1 }; 
 

namespace нужен, чтоб вынести константы енума из глобальной области видимости, для повышения читабельности и исключения пересечений.. 
а typedef для того чтоб был более удобный тип ePlayerStatus вместо PlayerStatus::eNum..

Добавлено через 4 минуты и 56 секунд
Цитата(borisbn @  22.7.2011,  20:10 Найти цитируемый пост)
    ePlayerStatus currentStatus() const {
        return m_currentStatus;
    }
    void setCurrentStatus( const ePlayerStatus & s ) {

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

Добавлено через 7 минут и 31 секунду
Цитата(borisbn @  23.7.2011,  08:18 Найти цитируемый пост)

Цитата
а после обращаться к его "вариантам" напрямую

обращаться можно (см. typedef от mes)

как typedef поможет обращаться к "вариантам" енума напрямую ?


Автор: boostcoder 23.7.2011, 11:41
Цитата(mes @  23.7.2011,  10:34 Найти цитируемый пост)
Вы думаете мы не в курсе ? ;)

smile 

Автор: borisbn 23.7.2011, 12:49
Цитата(mes @  23.7.2011,  10:34 Найти цитируемый пост)
старайтесь избегать интерфейса в виде сочетаний геттера и сеттера.. если нужно только это то лучше оформить как структурный блок данных, а не как класс.

под "только это" Вы имели в виду, что больше функциональности в классе нет ? Только private-член, геттер и сеттер ?
Если да, то что Вы понимаете под "оформить как структурный блок данных" ? Можно пример ?

Автор: mes 23.7.2011, 13:58
Цитата(borisbn @  23.7.2011,  11:49 Найти цитируемый пост)
под "только это" Вы имели в виду, что больше функциональности в классе нет ? Только private-член, геттер и сеттер ?

примерно.. грубо говоря,  если класс состоит только из гетеров и сеттеров.. 


Цитата(borisbn @  23.7.2011,  11:49 Найти цитируемый пост)
под "оформить как структурный блок данных" ? Можно пример ? 

Код

struct  {
 type1 data1;
 type2 data2;
};

 smile 

Автор: bsa 24.7.2011, 20:44

M
bsa
Сообщения относящиеся к обработке сетевого потока перенесены в тему Обработка сетевого потока

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)