Наследование классов C ++, как должен выглядеть конструктор? - PullRequest
0 голосов
/ 06 мая 2018

Я хочу написать код, который подсчитывает, сколько $ нужно заплатить клиентам в качестве телефонных счетов.

Я бы хотел иметь 3 типа контрактов:

Базовая: 10 $ / минута, 5 $ / SMS

SMSGod: 10 $ / минута, 1 $ / SMS и первые 150 бесплатных SMS

Улучшено: 5 $ / минута, 3 $ / SMS и первые 25 бесплатных SMS

Я хотел бы построить что-то вроде этого:

Класс, содержащий цену, которую клиент должен заплатить за звонки и SMS:

class BaseClass 
{
private: 
   int minutesPrice; 
   int SMSPrice;
public:
    setMinutesPrice(int x) { minutesPrice = x; }
    setSMSPrice(int x) { SMSPrice = x; }
};

И 3 потомка класса, какие типы контрактов вы могли видеть выше:

class Basic : public BaseClass 
{
public:
    Basic()
    {
        setMinutesPrice(10);
        setSMSPrice(5);
    }
}

class SMSGod : public BaseClass
{
private: 
   int freeSMS;
public: 
   SMSGod() 
   {
       setMinutesPrice(10);
       setSMSPrice(1);
       freeSMS = 150;
   }
}

class Upgraded: public BaseClass
{
private: 
   int freeSMS;
public: 
   Upgraded() 
   {
       setMinutesPrice(5);
       setSMSPrice(3);
       freeSMS = 25;
   }
}

Затем класс клиента:

class Client: public BaseClass
{
public:
    string name;
    string phoneNumber;
    string typeOfContract;
    int talkedMinutes;
    int sentSMS;
public:
Client(...){...}
};

А вот и моя проблема. Как я должен сделать конструктор Client (), чтобы иметь возможность построить Client first_client (...); объект. Как мне вызвать правильного конструктора: Basic , SMSGod или Модернизированный на основе typeOfContract .

Это должно работать:

Client Jack("Jack", "444-468-745", "Upgraded", 50, 25);

Затем другая функция также подсчитывает счет, исходя из того, сколько минут он говорил (50) , сколько отправленных им SMS (25) и из третьего параметра («Улучшено») Я могу использовать функции получения, чтобы узнать, какова базовая цена людей, которые получили «Обновленный» контракт, и сколько бесплатных SMS они получили.

(Это должно сработать в конце, чтобы рассчитать счет за телефон:

int havetopay(Client x)
{
   int freeSMS = x.getFreeSMS();
   int sentSMS = x.getSentSMS();
   int SMS;
   if (freeSMS > sentSMS) SMS = 0;
       else SMS = sentSMS - freeSMS;
   return (SMS * x.getSMSPrice() + x.getTalkedMinutes() * x.getMinutesPrice());
}

)

Спасибо за любую помощь!

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

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

class BasePlan 
{
private: 
   int minutesPrice; 
   int SMSPrice;
public:
    setMinutesPrice(int x) { minutesPrice = x; }
    setSMSPrice(int x) { SMSPrice = x; }
    virtual int calculateBill(int minutesTalked, int smsSent) = 0;
};

class Basic : public BasePlan 
{
public:
    Basic()
    {
        setMinutesPrice(10);
        setSMSPrice(5);
    }
    virtual int calculateBill(int minutesTalked, int smsSent) { return minutesTalked * minutesPrice + smsSent * SMSPrice;}
}

class SMSPlan : public BasePlan
{ 
private: 
   int freeSMS;
public: 
   SMSPlan(int minutesPrice, int smsPrice, int freeSMS) 
   {
       setMinutesPrice(minutesPrice);
       setSMSPrice(smsPrice);
       setFreeSMS(freeSMS);
   }

   public setFreeSMS(int free) { this.freeSMS = free; }

   virtual int calculateBill(int minutesTalked, int smsSent) { 
      int billedSMS = (freeSMS > sentSMS) ? 0 : sentSMS - freeSMS;
      return minutesTalked * minutesPrice + billedSMS * SMSPrice;}
}

class SMSGod : public SMSPlan 
{
public: 
   SMSGod() : SMSPlan(10, 1, 150)
   {
   }
}

class Upgraded: public SMSPlan 
{
public: 
   Upgraded() : SMSPlan(5, 3, 25) 
   {
   }
}

class Client
{
public:
    string name;
    string phoneNumber;
    BasePlan* currentPlan;
    int talkedMinutes;
    int sentSMS;
public:
Client(...){...}
void setPlan(BasePlan* plan) { this->currentPlan = setPlan(plan);}
int getBill() { return this->currentPlan->calculateBill(talkedMinutes, sentSMS); }
};

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

Client Jack = new Client("Jack", "444-468-745", 50, 25);
Jack.setPlan(new Upgraded());
int JacksBill = Jack.getBill();

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

0 голосов
/ 06 мая 2018

Ваш клиентский класс может быть классом шаблона, и на основании переданного параметра шаблона будет вызван соответствующий конструктор:

template <class T>
class Client:public T
{
  private:
     T Obj;
  public:
     T getObject() const
     {
        return Obj;
     } 

};
Client<SMSGod> c;

template<class T>
int havetopay(Client<T> clientObj)
{
   auto x = clientObj.getObject();
   int freeSMS = x.getFreeSMS();
   int sentSMS = x.getSentSMS();
   int SMS;
   if (freeSMS > sentSMS) SMS = 0;
       else SMS = sentSMS - freeSMS;
   return (SMS * x.getSMSPrice() + x.getTalkedMinutes() * x.getMinutesPrice());
}

Затем вы можете изменить функцию gettopay на шаблонную функцию

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