2016-09-27 3 views
0

Моя программа выводит странный набор чисел для каждого клиента и не получает имена каждого пользователя. Я не уверен, правильно ли я использую виртуальные функции, поскольку это для меня что-то относительно новое для меня концептуально.C++ с использованием виртуальных функций

Функция Compute_Bill() используется в каждом классе, поскольку Premium_Customer использует другой расчет для своих счетов, чем обычный клиент. Я прокомментировал стоимость расчетов для каждого счета.

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

Вот результат:

Заказчик обязан 10 долларов.

Клиент должен 20,4 доллара США.

Клиент обязан -7.02934e + 114 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент должен 20,4 доллара США.

Клиент должен 10 долларов.

Клиент обязан 1.24244e + 150 долларов.

А вот моя программа, сверху вниз начинается с класса Customer, то премиум класса, а затем главное:

#include <iostream> 

using namespace std; 

// CUSTOMER CLASS 
class Customer 
{ 
private: 
    double numCalls; 
    string name; 
    const double MONTH_FEE = 10; 
    const double PER_CALL = .5; 

protected: 
    double bill; 

public: 
    Customer(); 
    Customer(string aName, double aCalls); 
    virtual double Compute_Bill(); 
    string getName(); 
    void setName(string aName); 
    double getCalls(); 
    void setCalls(double aCalls); 
}; 

Customer::Customer() 
{ 
} 

Customer::Customer(string aName, double aCalls) 
{ 
    aName = ""; 
    aCalls = 0; 
} 

string Customer::getName() 
{ 
    return name; 
} 

void Customer::setName(string aName) 
{ 
    aName = name; 
} 

double Customer::getCalls() 
{ 
    return numCalls; 
} 

void Customer::setCalls(double aCalls) 
{ 
    aCalls = numCalls; 
} 

// Computing the bill for the Customer, uses 
// bill = monthlyfee + (percallrate * numcalls) 
// monthly fee = $10 
// per call charge = .50 
double Customer::Compute_Bill() 
{ 
    bill = MONTH_FEE + (PER_CALL * numCalls); 
    return bill; 
} 


// PREMIUM_CUSTOMER CLASS 
class Premium_Customer : public Customer 
{ 
private: 
    double numCalls; 
    string name; 
    const double MONTH_FEE = 20; 
    const double PER_CALL = .05; 
    const double PER_MINUTE = .1; 
    const double NUM_MINS = 4; 

protected: 
    double bill; 

public: 
    Premium_Customer(); 
    Premium_Customer(string aName, double aCalls); 
    virtual double Compute_Bill(); 
    string getName(); 
    void setName(string aName); 
    double getCalls(); 
    void setCalls(double aCalls); 
}; 

Premium_Customer::Premium_Customer() 
{ 
} 

Premium_Customer::Premium_Customer(string aName, double aCalls) 
{ 
    aName = ""; 
    aCalls = 0; 
} 

string Premium_Customer::getName() 
{ 
    return name; 
} 

void Premium_Customer::setName(string aName) 
{ 
    aName = name; 
} 

double Premium_Customer::getCalls() 
{ 
    return numCalls; 
} 

void Premium_Customer::setCalls(double aCalls) 
{ 
    aCalls = numCalls; 
} 

// Computing the bill for the Premium_Customer, uses 
// bill = monthlyfee + (percallrate * numcalls) + (permin_callrate * nummins) 
// monthly fee = $20 
// per call charge = .05 
// per minute call rate = .10 
// nummins = 4 
double Premium_Customer::Compute_Bill() 
{ 
    bill = MONTH_FEE + (PER_CALL * numCalls) + (PER_MINUTE * NUM_MINS); 
    return bill; 
} 

// MAIN CLASS 
int main() { 
    Customer* list[18] ; 
    list[0] = new Customer("John Dough", 20); 
    list[1] = new Premium_Customer("Bob Dough", 20); 
    list[2] = new Customer("Tim Dough", 30); 
    list[3] = new Premium_Customer("Jane Dough", 30); 
    list[4] = new Customer("Bill Dough", 40); 
    list[5] = new Premium_Customer("Tom Dough", 40); 
    list[6] = new Customer("Jim Dough", 50); 
    list[7] = new Premium_Customer("Kane Dough", 50); 
    list[8] = new Customer("Hon Dough", 60); 
    list[9] = new Premium_Customer("Jill Dough", 60); 
    list[10] = new Customer("Mary Dough", 70); 
    list[11] = new Premium_Customer("Un Dough", 70); 
    list[12] = new Customer("Sarah Dough", 80); 
    list[13] = new Premium_Customer("Liz Dough", 80); 
    list[14] = new Customer("Will Dough", 90); 
    list[15] = new Premium_Customer("Mike Dough", 90); 
    list[16] = new Customer("Brian Dough", 100); 
    list[17] = new Premium_Customer("Kurt Dough", 100); 
    for(int i=0; i<18; i++) { 
     cout << "Customer " << list[i]->getName() << " owes " 
     << list[i]->Compute_Bill() << " dollars." << endl; 
    } 
    // delete all the customers 
    return 1; 
} 
+0

Ваши конструкторы, похоже, неправильно задают переменные-члены. И то же самое касается многих ваших функций. Попробуйте передать входы const/const & в функции, которые должны устанавливать переменные, чтобы поймать ошибки. –

+0

@ RobertPrévost вы можете объяснить, почему они ошибаются? – Yoyokolo

+0

Возьмите 'Customer :: Customer (строка aName, double aCalls)' например. Вместо того, чтобы устанавливать переменные-члены, вместо этого устанавливаются временные входные переменные. –

ответ

1

У вас было много мелких ошибок. Твой удел был в основном хорошо, вам просто нужно удалить части, которые вы не нужны:

#include <iostream> 
#include <string> 

using namespace std; 

// CUSTOMER CLASS 
class Customer 
{ 
private: 
    double numCalls; 
    string name; 
    const double MONTH_FEE = 10; 
    const double PER_CALL = .5; 

protected: 
    double bill; 

public: 
    Customer(); 
    Customer(const string& aName, double aCalls); 
    virtual double Compute_Bill(); 
    string getName() const; 
    void setName(const string& aName); 
    double getCalls() const; 
    void setCalls(double aCalls); 
}; 

Customer::Customer() 
{ 
} 

Customer::Customer(const string& aName, double aCalls) 
{ 
    setName(aName); 
    setCalls(aCalls); 
} 

string Customer::getName() const 
{ 
    return name; 
} 

void Customer::setName(const string& aName) 
{ 
    // you had this mixed up 
    name = aName; 
} 

double Customer::getCalls() const 
{ 
    return numCalls; 
} 

void Customer::setCalls(double aCalls) 
{ 
    // this was mixed up too 
    numCalls = aCalls; 
} 

// Computing the bill for the Customer, uses 
// bill = monthlyfee + (percallrate * numcalls) 
// monthly fee = $10 
// per call charge = .50 
double Customer::Compute_Bill() 
{ 
    bill = MONTH_FEE + (PER_CALL * numCalls); 
    return bill; 
} 


// PREMIUM_CUSTOMER CLASS 
class Premium_Customer : public Customer 
{ 
private: 
    const double MONTH_FEE = 20; 
    const double PER_CALL = .05; 
    const double PER_MINUTE = .1; 
    const double NUM_MINS = 4; 

public: 
    Premium_Customer(); 
    Premium_Customer(const string& aName, double aCalls); 
    virtual double Compute_Bill(); 
    // the other methods are already inherited, no need to implement them again... 
}; 

Premium_Customer::Premium_Customer() 
{ 
} 

// no special logic here, just delegate to your base class constructor 
Premium_Customer::Premium_Customer(const string& aName, double aCalls) : Customer(aName, aCalls) 
{ 
} 

// Computing the bill for the Premium_Customer, uses 
// bill = monthlyfee + (percallrate * numcalls) + (permin_callrate * nummins) 
// monthly fee = $20 
// per call charge = .05 
// per minute call rate = .10 
// nummins = 4 
double Premium_Customer::Compute_Bill() 
{ 
    // no direct access to private customer variables here, used getCalls method instead 
    bill = MONTH_FEE + (PER_CALL * getCalls()) + (PER_MINUTE * NUM_MINS); 
    return bill; 
} 

// MAIN CLASS 
int main() { 
    Customer* list[18]; 
    list[0] = new Customer("John Dough", 20); 
    list[1] = new Premium_Customer("Bob Dough", 20); 
    list[2] = new Customer("Tim Dough", 30); 
    list[3] = new Premium_Customer("Jane Dough", 30); 
    list[4] = new Customer("Bill Dough", 40); 
    list[5] = new Premium_Customer("Tom Dough", 40); 
    list[6] = new Customer("Jim Dough", 50); 
    list[7] = new Premium_Customer("Kane Dough", 50); 
    list[8] = new Customer("Hon Dough", 60); 
    list[9] = new Premium_Customer("Jill Dough", 60); 
    list[10] = new Customer("Mary Dough", 70); 
    list[11] = new Premium_Customer("Un Dough", 70); 
    list[12] = new Customer("Sarah Dough", 80); 
    list[13] = new Premium_Customer("Liz Dough", 80); 
    list[14] = new Customer("Will Dough", 90); 
    list[15] = new Premium_Customer("Mike Dough", 90); 
    list[16] = new Customer("Brian Dough", 100); 
    list[17] = new Premium_Customer("Kurt Dough", 100); 

    for (int i = 0; i<18; i++) { 
     cout << "Customer " << list[i]->getName() << " owes " << list[i]->Compute_Bill() << " dollars." << endl; 
    } 

    // delete all the customers 
    return 0; 
} 
+0

Я верю, что вы помогли мне раньше. Еще раз, спасибо. Всегда есть мелочи, которые меня так любят. Но я люблю учиться на своих ошибках! Спасибо! – Yoyokolo

0

Ваш код Неопределенное поведение, так как ваши конструкторы не инициализировать поля-члены. В частности, член numCalls никогда не инициализируется и используется для результата метода Compute_Bill.

инструменты, такие как точки VALGRIND на такие ошибки: на вашем коде, Valgrind говорит

by 0x401C55: main (file.cpp:157) 
Conditional jump or move depends on uninitialised value(s) 

На самом деле в ваших методах setCall, вам следует определить

numCalls = aCall; 

и не

aCall = numCalls; 

, который не влияет, поскольку влияет на параметр.

Смежные вопросы