C ++使用虚函数

时间:2016-09-27 15:36:57

标签: c++ virtual-functions

我的程序正在为每个客户输出一组奇怪的数字,而不是让每个客户都得到这样的数字。名。我不确定我是否正确使用虚拟功能,因为这在概念上对我来说相对较新。

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类开始,然后是Premium Class,然后是main:

#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;
}

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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;

没有任何效果,因为它确实会影响参数。