Перечислимые типы данных и API классов в C ++ - PullRequest
0 голосов
/ 17 мая 2009

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

enum PizzaType {DEEP_DISH, HAND_TOSSED, PAN};
enum PizzaSize {SMALL, MEDIUM, LARGE};

class Pizza {
    public:
        Pizza();
        void setPizzaType(PizzaType type);
        PizzaType getPizzaType();
        void setPizzaSize(PizzaSize size);
        PizzaSize getPizzaSize();
        void setToppings(int toppings);
        int getToppings();
        void outputDescription();
        double computePrice();
    private:
        PizzaType pizzaType;
        PizzaSize pizzaSize;
        int totalToppings;
};

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

Ответы [ 6 ]

5 голосов
/ 17 мая 2009

Да, вы можете сделать это так:

class Pizza {
    public:
        enum PizzaType {DEEP_DISH, HAND_TOSSED, PAN};
        enum PizzaSize {SMALL, MEDIUM, LARGE};

        Pizza();
        void setPizzaType(PizzaType type);
        PizzaType getPizzaType();
        void setPizzaSize(PizzaSize size);
        PizzaSize getPizzaSize();
        void setToppings(int toppings);
        int getToppings();
        void outputDescription();
        double computePrice();
    private:
        PizzaType pizzaType;
        PizzaSize pizzaSize;
        int totalToppings;
};

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

Pizza::PizzaType tmp = pPizza->getPizzaType();

и т. Д. И т. П.

(Как примечание стиля, когда вы помещаете перечисления внутри класса таким образом, я бы лично удалил Pizza перед ним, чтобы у вас были Pizza :: Type и Pizza :: Size.)

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

Предпочтительный метод использования перечислений в C ++ - определить их внутри класса:

class Foo {
public:
     enum Bar {
         ENUM_VALUE1,
         ENUM_VALUE2
     };
};

Затем вы можете ссылаться на них, используя:

Foo::Bar var;
var = Foo::ENUM_VALUE1;

Внутри класса вы можете удалить префикс Foo::.

Как вы, вероятно, заметили, хотя тип перечисления Foo::Bar, на значения не ссылаются через Foo::Bar::ENUM_VALUE1, а скорее появляются в пространстве имен Foo. Это может быть проблематично, если разные перечисления имеют одинаковые имена значений. Чтобы избежать этого, вы можете сделать следующий трюк:

class Foo {
public:
      struct Bar {
             enum ENUM {
                  ENUM_VALUE1,
                  ENUM_VALUE2
             };
      struct Baz {
             enum ENUM {
                  ENUM_VALUE1,
                  ENUM_VALUE2
             };
      };
};
Foo::Bar::ENUM e = Foo::Bar::ENUM_VALUE1;
Foo::Baz::ENUM e2 = Foo::Baz::ENUM_VALUE1;
3 голосов
/ 17 мая 2009
class Pizza {
    public:
        enum PizzaType {DEEP_DISH, HAND_TOSSED, PAN};
        void setPizzaType(PizzaType type);
        PizzaType getPizzaType();
};
...
Pizza p;
p.setPizzaType( Pizza::DEEP_DISH );
Pizza::PizzaType pt = p.getPizzaType();
1 голос
/ 17 мая 2009

Вы можете определить enum внутри класса и использовать его снаружи, например, как вы используете пространство имен, т.е. classname :: enum_type. На самом деле, это хорошая идея определить его внутри класса, так как он позволяет избежать загрязнения глобального пространства имен.

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

Пока тип перечисления является общедоступным, вы можете использовать его вне класса. Вы просто должны охватить это я: Pizza :: PizzaType. Это же правило существует для статических методов и для статических констант и переменных.

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

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

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

Pizza p;
p.setPizzaType(Pizza::PAN);
Pizza::PizzaType pt = p.getPizzaType();
assert(pt == Pizza::PAN);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...