Как инициализировать статический член const, являющийся массивом другого класса, и использовать его? - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь создать торговый автомат с инвентарем. В инвентаре я планировал стать массивом классных напитков. Вот что я написал до сих пор.

VendingMachine.h - должен содержать массив класса Drinks

#include "Drinks.h"

class VendingMachine {
   private:
      static const int NUM_DRINKS = 5;
      static const Drinks drinks[NUM_DRINKS];
   public:
      VendingMachine();
};

Теперь Drinks.h

#include <string>

class Drinks {
   private:
      std::string name;
      double price;
      int qtyInMachine;
   public:
      Drinks(std::string name, double price, int qtyInMachine);
      void decrementQuantity();
};

VendingMachine.cpp

#include "VendingMachine.h"

VendingMachine::VendingMachine() {
}

Drinks.cpp

#include <string>
#include "Drinks.h"

Drinks::Drinks(std::string n, double p, int qty) : name(n), price(p), qtyInMachine(qty) {
}
void Drinks::decrementQuantity() {
   qtyInMachine--;
}

Теперь для тестовой программы

#include <iostream>
#include "VendingMachine.h"

const Drinks VendingMachine::drinks[VendingMachine::NUM_DRINKS] {Drinks("Cola",1.25,20),
      Drinks("Root Beer",1.35,20),Drinks("Orange Soda",1.20,20),Drinks("Grape Soda",1.20,20),
      Drinks("Bottled Water",1.55,20)};

int main() {
   VendingMachine vm1;
   for (int i = 0; i < VendingMachine::NUM_DRINKS; i++) {
      std::cout << vm1.drinks[i].name << " ";
   }
}

Строка, где я определяю напитки, компилятор жалуется, что он не является целочисленным-expression и что VendingMachine :: NUM_DRINKS является закрытым в контексте. Он утверждает, что та же самая ошибка частного контекста для моего оператора for с NUM_DRINKS, также в моем утверждении cout, он заявляет то же самое для обоих напитков и имени. Мне нужно знать, как и где инициализировать напитки и как их использовать в основном, не получая ошибок «private in this context».

Поскольку я начинающий с классов и OO в целом, я не могу найти свойошибка. Любая помощь с благодарностью.

1 Ответ

1 голос
/ 02 октября 2019

На самом деле, вам необходимо изучить / пересмотреть концепции ООП инкапсуляции и сокрытия данных вместе со специфическими для С ++ функциями спецификаторов доступа (private и public), а также тем, как они используются и в каком контексте.

Примечание: есть также спецификатор доступа protected, вы изучите его в теме наследования.

  • public часть класса видна внешнему миру, например, другие классы, функции и т. д.
  • private доступен только внутри самого класса.

У вас есть личные члены, к которым вы обращаетесь в контексте public, поэтому вы 'Вы получаете эти ошибки, например:

class VendingMachine {
   private:
      static const int NUM_DRINKS = 5;          // private to class
      static const Drinks drinks[NUM_DRINKS];   // private to class
   public:
      VendingMachine(){}
};

и в main функция:

int main() {
   VendingMachine vm1;
   for (int i = 0; i < VendingMachine::NUM_DRINKS; i++) { // accessing private member VendingMachine::NUM_DRINKS
      std::cout << vm1.drinks[i].name << " ";             // accessing private members vm1.drinks[i].name
   }
}

Член данных name равен private для класса Drinks, и вы получаете доступэто публично в main.

Это проблемы, которые вам нужно исправить.

Для доступа к частному элементу данных обычно используется функция доступа, например, для доступа к nameу вас будет публичный метод getName() и т. д.

  • To для доступа к частным элементам данных экземпляра вам понадобятся открытые методы.
  • Для доступа к private static членам данных или членам класса вам понадобится public static функций-членов.

Еще одна вещь, на которую я хотел бы обратить внимание:

// Declaration: Observe names of the method arguments
Drinks(std::string name, double price, int qtyInMachine); 

// Definition: Observe the names of the arguments here 
Drinks::Drinks(std::string n, double p, int qty) : name(n), price(p), qtyInMachine(qty) {
}

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


Вот минимальный модифицированный рабочий пример: http://ideone.com/tr5oZu

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