-1

I have a QT Project where I've been given a UML diagram and some instructions (See below) Question

I've been so lost as to what I'm doing so I'm just going to show all my code, it's finished but not working... The main error I get now is the Constructors for all the transaction types (deposit, withdrawal and balance enquiry) give a "no matching function for call to 'Transaction::Transaction()'" error. I may just be doing this all wrong. Appreciate any help I can get...

Here is all my code: savingsaccount.h

    #ifndef SAVINGSACCOUNT_H
    #define SAVINGSACCOUNT_H
    #include "transaction.h"
    #include "deposit.h"
    #include "balanceenquiry.h"
    #include "withdrawal.h"

    class SavingsAccount
    {
    private:
        QString m_CustomerName;
        QString m_AccountNumber;
        QList<Transaction*> m_TransactionList;
    public:
        SavingsAccount(QString name, QString num);
        ~SavingsAccount();
        void addTransaction(Transaction* t);
        double totalTransactionCost();
        QString frequentTransactionType();
        QList<Transaction*> transactionsOnAdate(QDate date);
        QString toString() const;
    };

    #endif // SAVINGSACCOUNT_H

savingsaccount.cpp

#include "savingsaccount.h"

SavingsAccount::SavingsAccount(QString name, QString num) {
    m_CustomerName = name;
    m_AccountNumber = num;
}
SavingsAccount::~SavingsAccount() {
    while(!m_TransactionList.isEmpty()) {
        delete m_TransactionList.takeFirst();
    } //Deletes all list items
}
SavingsAccount::addTransaction(Transaction* t) {
    m_TransactionList << t; //Adds transaction to list
}
double SavingsAccount::totalTransactionCost() {
    double totalCost;

    for(int i = 0; i < m_TransactionList.size(); i++) {
        totalCost += m_TransactionList.at(i)->computeCost();
    }

    return totalCost; //Returns total transaction cost
}
QString SavingsAccount::frequentTransactionType() {
    QString frequentType;
    int deposit, withdrawal, balanceEnquiry;

    for(int i = 0; i < m_TransactionList.size(); i++) {
        if(m_TransactionList.at(i)->getType() == "Deposit") {
            deposit++;
        }
        else if(m_TransactionList.at(i)->getType() == "Withdrawal") {
            withdrawal++;
        }
        else if(m_TransactionList.at(i)->getType() == "Balance Enquiry") {
            balanceEnquiry++;
        }
    }

    if(deposit > withdrawal && deposit > balanceEnquiry) {
        frequentType = "Deposit";
    } else if(withdrawal > balanceEnquiry && withdrawal > deposit) {
        frequentType = "Withdrawal";
    } else if(balanceEnquiry > deposit && balanceEnquiry > withdrawal) {
        frequentType = "Balance Enquiry";
    }
    else {
        frequentType = "NA";
    }

    return frequentType;//Returns most frequent transaction type
}
QList<Transactions*> SavingsAccount::transactionsOnDate(QDate date) {
    QList<Transaction*> transactions;

    for(int i = 0; i < m_TransactionList.size(); i++) {
        if(m_TransactionList.at(i)->getDateTime().date() == date) {
            transactions << m_TransactionList;
        }
    }

    return transactions;
}
QString SavingsAccount::toString() {
    return "Savings Account:\n================\n"
           + "Customer Name: " + m_CustomerName + "\n"
           + "Account Number: " + m_AccountNumber + "\n"
           + "================\nTransactions\n================\n"
           + m_TransactionList
           + "================\nTransaction Details\n================\n"
           + "Total Transaction Cost: R" + totalTransactionCost()
           + "Most Frequent Transaction Type: " + frequentTransactionType()
           + "================\nTransactions Today\n================"
           + transactionsOnAdate(QDate::currentDate());
}

transaction.h

#ifndef TRANSACTION_H
#define TRANSACTION_H
#include <QString>
#include <QDateTime>

class Transaction
{
protected:
    QString m_Type;
    QDateTime m_DateTime;
public:
    Transaction(QString type, QDateTime datetime);
    QString getType();
    QString toString();
    QDateTime getDateTime();
    virtual double computeCost();
};

transaction.cpp

#include "transaction.h"

Transaction::Transaction(QString type, QDateTime datetime) {
    m_Type = type;
    m_DateTime = datetime;
}
QString Transaction::getType() {
    return m_Type;
}
QString Transaction::toString() {
    return m_Type + " " + m_DateTime.toString() + "\n";
}
QDateTime Transaction::getDateTime() {
    return m_DateTime;
}
double Transaction::computeCost() {
    return 0;//Virtual Function (meant to be overrided)
}

deposit.h

#ifndef DEPOSIT_H
#define DEPOSIT_H
#include "transaction.h"
#include <QString>

class Deposit: public Transaction
{
private:
    double m_Amount;
    const double m_Fee = 5.0; //reasonable amount R5 deposit
public:
    Deposit(double amount);
    QString toString();
    double computeCost();
};

#endif // DEPOSIT_H

deposit.cpp

#include "deposit.h"

Deposit::Deposit(double amount) {
    m_Amount = amount;
    m_Type = "Deposit";
    m_DateTime = QDateTime::currentDateTime();
}
QString Deposit::toString() {
    return Transaction::toString() + "Amount: R" + m_Amount
            + "\nFee: R" + m_Fee;
}
double Deposit::computeCost() {
    return m_Fee;
}

withdrawal.h

#ifndef WITHDRAWAL_H
#define WITHDRAWAL_H
#include "transaction.h"
#include <QString>

class Withdrawal: public Transaction
{
private:
    double m_Amount;
    double m_Percentage = 3; //3% withdrawal cost
public:
    Withdrawal(double amount);
    QString toString() const;
    double computeCost();
};

#endif // WITHDRAWAL_H

withdrawal.cpp

#include "withdrawal.h"

Withdrawal::Withdrawal(double amount) {
    m_Amount = amount;
    m_Type = "Withdrawal";
    m_DateTime = QDateTime::currentDateTime();
}
QString Withdrawal::toString() {
    return Transaction::toString() + "Amount: R" + m_Amount
            + "\nFee Percentage: " + m_Percentage + "%";
}
double Withdrawal::computeCost() {
    return m_Amount*m_Percentage/100;
}

balanceenquiry.h

#ifndef BALANCEENQUIRY_H
#define BALANCEENQUIRY_H
#include "transaction.h"
#include <QString>
#include <QDate>

class BalanceEnquiry: public Transaction
{
private:
    QDate m_FromDate;
    QDate m_ToDate;
public:
    BalanceEnquiry(QDate fDate, QDate tDate);
    QString toString() const;
    double computeCost();
};

#endif // BALANCEENQUIRY_H

balanceenquiry.cpp

#include "balanceenquiry.h"

BalanceEnquiry::BalanceEnquiry(QDate fDate, QDate tDate) {
    m_FromDate = fDate;
    m_ToDate = tDate;
    m_Type = "Balance Enquiry";
    m_DateTime = QDateTime::currentDateTime();
}
QString BalanceEnquiry::toString() {
    return Transaction::toString() + "From: " + m_FromDate
            + "/nTo: " + m_ToDate;
}
double BalanceEnquiry::computeCost() {
    return 0; //Balance Enquiry costs nothing
}

main.cpp

#include <QCoreApplication>
#include "savingsaccount.h"
#include <QDebug>

QTextStream cout(stdout);

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //Declare variables
    QString customerName = "Barry Doyle";
    QString accountNumber = "1234567890";

    //Implement Savings Account
    SavingsAccount account(customerName, accountNumber);

    //Implement Transactions
    Deposit d1(500.0);
    BalanceEnquiry b1(QDate::currentDate(), QDate::currentDate());
    Withdrawal w1(200.0);
    Withdrawal w2(250.0);
    BalanceEnquiry b2(QDate::currentDate(), QDate::currentDate());
    Deposit d2(400.0);
    Deposit d3(150.0);

    Transaction *t1 = &d1;
    Transaction *t2 = &b1;
    Transaction *t3 = &w1;
    Transaction *t4 = &w2;
    Transaction *t5 = &b2;
    Transaction *t6 = &d2;
    Transaction *t7 = &d3;

    //Add Transactions to Transaction List
    account.addTransaction(t1);
    account.addTransaction(t2);
    account.addTransaction(t3);
    account.addTransaction(t4);
    account.addTransaction(t5);
    account.addTransaction(t6);
    account.addTransaction(t7);

    account.toString();

    return a.exec();
}
Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
  • 1
    Have a closer look at the class diagram for `Transaction`. The method `computeCost` is in italics. This means that the entire class is an abstract class and `computeCost` should be defined as pure virtual. ie, it should not have a function body defined in transaction.cpp and should be defined as `virtual double computeCost() = 0;` – RobbieE Mar 28 '15 at 07:55
  • Thanks, don't really have any experience or understanding of how these virtual functions work... I've done that but it gives me an error saying 'virtual' outside class declaration and function 'double computeCost()' is initialized like a variable – Barry Michael Doyle Mar 28 '15 at 11:38
  • 1
    You misunderstood, pure virtual functions are declared inside the class definition. See http://www.learncpp.com/cpp-tutorial/126-pure-virtual-functions-abstract-base-classes-and-interface-classes/ – RobbieE Mar 28 '15 at 11:46

2 Answers2

0

For example: Deposit is derived from Transaction. Deposit constructor implicitly calls Transaction constructor with no arguments - Transaction(), but it doesn't exist. So to solve your problem you should define Transaction constructor without arguments - Transaction(), or call explicitly constructor with 2 arguments Transaction(QString type, QDateTime datetime) like this:

Deposit::Deposit(double amount)
        : Transaction("Deposit", QDateTime::currentDateTime()) {
m_Amount = amount;
m_Type = "Deposit"; // this no need now
m_DateTime = QDateTime::currentDateTime(); // and this too

}

Yaroslav
  • 104
  • 1
  • 5
0

I think for ua addTransaction you should use the append function like

void SavingsAccount::addTransaction(Transaction *t){
    m_TransactionList.append();
Robert
  • 5,278
  • 43
  • 65
  • 115
bianca
  • 1