Search code examples
c++qtinheritancebase-classqlist

Issues with Inheritance C++ Qt Project


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();
}

Solution

  • 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
    

    }