Home > OS >  LNK2019: unresolved external symbol - linking .h files with .cpp (definition) files in Visual Studio
LNK2019: unresolved external symbol - linking .h files with .cpp (definition) files in Visual Studio

Time:02-10

Okay, so I'm currently a beginner programmer for C (year 11 in school, 3rd year of high school but we're still studying basic functions, so please excuse any rookie mistakes) and I'm learning additional coding knowledge by myself. Context aside, I moved to Visual Studio 2022 and I'm following a course, currently learning about Inheritance.

Thing is, I have a project with a base Account class and 3 other publicly derived classes (from the Account class) and each of these have headers and definition files, but whenever I try to run the main I get the following error chain:

1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl deposit(class std::vector<class Account,class std::allocator<class Account> > const &,double)" (?deposit@@YAXAEBV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl deposit(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?deposit@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::deposit(double)" (?deposit@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl SavingsAccount::deposit(double)" (?deposit@SavingsAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::deposit(double)" (?deposit@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl withdraw(class std::vector<class Account,class std::allocator<class Account> > const &,double)" (?withdraw@@YAXAEBV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl withdraw(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?withdraw@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::withdraw(double)" (?withdraw@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl CheckingAccount::withdraw(double)" (?withdraw@CheckingAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::withdraw(double)" (?withdraw@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl deposit(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > const &,double)" (?deposit@@YAXAEBV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl deposit(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?deposit@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::deposit(double)" (?deposit@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl SavingsAccount::deposit(double)" (?deposit@SavingsAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::deposit(double)" (?deposit@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl withdraw(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > const &,double)" (?withdraw@@YAXAEBV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl withdraw(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?withdraw@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::withdraw(double)" (?withdraw@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl CheckingAccount::withdraw(double)" (?withdraw@CheckingAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::withdraw(double)" (?withdraw@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl deposit(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > const &,double)" (?deposit@@YAXAEBV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl deposit(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?deposit@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::deposit(double)" (?deposit@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl SavingsAccount::deposit(double)" (?deposit@SavingsAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::deposit(double)" (?deposit@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl withdraw(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > const &,double)" (?withdraw@@YAXAEBV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl withdraw(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?withdraw@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::withdraw(double)" (?withdraw@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl CheckingAccount::withdraw(double)" (?withdraw@CheckingAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::withdraw(double)" (?withdraw@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl deposit(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > const &,double)" (?deposit@@YAXAEBV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl deposit(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?deposit@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl deposit(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?deposit@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::deposit(double)" (?deposit@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl SavingsAccount::deposit(double)" (?deposit@SavingsAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::deposit(double)" (?deposit@TrustAccount@@QEAA_NN@Z)
1>SectionChallenge.obj : error LNK2019: unresolved external symbol "void __cdecl withdraw(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > const &,double)" (?withdraw@@YAXAEBV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z) referenced in function main
1>  Hint on symbols that are defined and could potentially match:
1>    "void __cdecl withdraw(class std::vector<class Account,class std::allocator<class Account> > &,double)" (?withdraw@@YAXAEAV?$vector@VAccount@@V?$allocator@VAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class CheckingAccount,class std::allocator<class CheckingAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VCheckingAccount@@V?$allocator@VCheckingAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class SavingsAccount,class std::allocator<class SavingsAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VSavingsAccount@@V?$allocator@VSavingsAccount@@@std@@@std@@N@Z)
1>    "void __cdecl withdraw(class std::vector<class TrustAccount,class std::allocator<class TrustAccount> > &,double)" (?withdraw@@YAXAEAV?$vector@VTrustAccount@@V?$allocator@VTrustAccount@@@std@@@std@@N@Z)
1>    "public: bool __cdecl Account::withdraw(double)" (?withdraw@Account@@QEAA_NN@Z)
1>    "public: bool __cdecl CheckingAccount::withdraw(double)" (?withdraw@CheckingAccount@@QEAA_NN@Z)
1>    "public: bool __cdecl TrustAccount::withdraw(double)" (?withdraw@TrustAccount@@QEAA_NN@Z)
1>C:\Users\Sapok\Desktop\Programming_projects\Visual Studio\ConstructorsAndDestructors\x64\Debug\3. Inheritance - DerivingClasses.exe : fatal error LNK1120: 8 unresolved externals

From what I've gathered, the compiler is either pissed that it hasn't found any definitions for the functions I declared in the headers, or it's pissed that it can't tell apart between the "deposit" and "withdraw" functions for each class (each class has those 2 methods and they're named the same everywhere, but inheritance should make it work fine, I've checked the code itself and no other compiler errors appear). At this point, I'm genuinely stumped as to what the hell the compiler's crying about and how to fix it.

I've tried to include all the headers in all the files, all the .cpp files everywhere. Including the .cpp files only makes it spit out the LNK1169 (multiply defined symbols) instead, so no bueno. I've tried copying everything to a fresh solution and to no avail, I've double and triple checked all the code, I've tried moving files around, I've scoured a number of posts talking about this same type of error and none of them seem to help.

(A screenshot of my project's file distribution): https://i.stack.imgur.com/gOXym.png

For example's sake, here's my base Account class header...

#ifndef _ACCOUNT_H_
#define _ACCOUNT_H_
#include <string>
#include <iostream>

class Account {
    friend std::ostream& operator<< (std::ostream &out, const Account& account);
private:
    static constexpr const char* def_name = "Unnamed account";
    static constexpr double def_balance = 0.0;
protected:
    std::string name;
    double balance;
public:
    Account(std::string name = def_name, double balance = def_balance);
    bool deposit(double amount);
    bool withdraw(double amount);
};

#endif // _ACCOUNT_H_

...and its definition .cpp file.

#include "Account.h"
#include <string>
#include <iostream>

Account::Account(std::string name, double balance)
    : name{ name }, balance{ balance } {}

bool Account::deposit(double amount) {
    if (amount < 0)
        return false;
    else {
        balance  = amount;
        return true;
    }
}

bool Account::withdraw(double amount) {
    if (balance - amount < 0)
        return false;
    else {
        balance -= amount;
        return true;
    }
}

std::ostream& operator<<(std::ostream& out, const Account& account) {
    out << "[Account: " << account.name << ": " << account.balance << "]";
    return out;
}

All the other classes are very similar, as inheritance usually works.

Sorry for the long-winded explanation, I'm still new to all this and I just wanna make sure I get all the necessary details across. If anyone has any general etiquette tips for help posts like this one, that'd be greatly appreciated as well :)

Thanks in advance!

Edit: I'll include all the code - I think this isn't clear enough.

Account.h and Account.cpp are included above

SavingsAccount.h:

#ifndef _SAVINGSACCOUNT_H_
#define _SAVINGSACCOUNT_H_
#include "Account.h"
#include <string>
#include <iostream>

class SavingsAccount : public Account{
    friend std::ostream& operator<< (std::ostream& out, const SavingsAccount& account);
private:
    static constexpr const char* def_name = "Unnamed account";
    static constexpr double def_balance = 0.0;
    static constexpr double def_interest = 0.0;
protected:
    double interest;
public:
    SavingsAccount(std::string name = def_name, double balance = def_balance, double interest = def_interest);
    bool deposit(double amount);
    // Inherited withdraw
};

#endif // _SAVINGSACCOUNT_H_

SavingsAccount.cpp:

#include "SavingsAccount.h"
#include "Account.h"
#include <string>
#include <iostream>

SavingsAccount::SavingsAccount(std::string name, double balance, double interest)
    : Account(name, balance), interest{ interest } {}

bool SavingsAccount::deposit(double amount) {
    amount  = amount * (interest / 100);
    return Account::deposit(amount);
}

std::ostream& operator<<(std::ostream& out, const SavingsAccount& account) {
    out << "[SavingsAccount: " << account.name << ": " << account.balance << ", " << account.interest << "%]";
    return out;
}

CheckingAccount.h:

#ifndef _CHECKINGACCOUNT_H_
#define _CHECKINGACCOUNT_H_
#include "Account.h"
#include <string>
#include <iostream>

class CheckingAccount : public Account {
    friend std::ostream& operator<< (std::ostream& out, const CheckingAccount& account);
private:
    static constexpr const char* def_name = "Unnamed account";
    static constexpr double def_balance = 0.0;
    static constexpr double def_fee = 1.5;
public:
    CheckingAccount(std::string name = def_name, double balance = def_balance);
    // Inherited deposit
    bool withdraw(double amount);
};

#endif // _CHECKINGACCOUNT_H_

CheckingAccount.cpp:

#include "CheckingAccount.h"
#include "Account.h"
#include <string>
#include <iostream>

CheckingAccount::CheckingAccount(std::string name, double balance)
    : Account(name, balance) {}

bool CheckingAccount::withdraw(double amount) {
    amount  = def_fee;
    return Account::withdraw(amount);
}

std::ostream& operator<<(std::ostream& out, const CheckingAccount& account) {
    out << "[CheckingAccount: " << account.name << ": " << account.balance << ", " << account.def_fee << " withdrawal fee]";
    return out;
}

TrustAccount.h:

#ifndef _TRUSTACCOUNT_H_
#define _TRUSTACCOUNT_H_
#include "SavingsAccount.h"
#include "Account.h"
#include <string>
#include <iostream>

class TrustAccount : public SavingsAccount {
    friend std::ostream& operator<< (std::ostream& out, const TrustAccount& account);
private:
    static constexpr const char* def_name = "Unnamed account";
    static constexpr double def_balance = 0.0;
    static constexpr double def_interest = 0.0; 
    static constexpr double def_bonus = 50.0;
    static constexpr double def_minimum = 0.2;
protected:
    int limit;
public:
    TrustAccount(std::string name = def_name, double balance = def_balance, double interest = def_interest, int limit = 0);
    bool deposit(double amount);
    bool withdraw(double amount);
};

#endif // _TRUSTACCOUNT_H_

TrustAccount.cpp:

#include "TrustAccount.h"
#include "SavingsAccount.h"
#include "Account.h"
#include <string>
#include <iostream>

TrustAccount::TrustAccount(std::string name, double balance, double interest, int limit)
    : SavingsAccount(name, balance, interest), limit{ 0 } {}

bool TrustAccount::deposit(double amount) {
    if (!SavingsAccount::deposit(amount))
        return false;
    if (amount >= 5000)
        Account::deposit(def_bonus);
    return true;
}

bool TrustAccount::withdraw(double amount) {
    if ((limit >= 3) || (amount > (balance * def_minimum)))
        return false;
    limit  ;
    return SavingsAccount::withdraw(amount);
}

std::ostream& operator<<(std::ostream& out, const TrustAccount& account) {
    out << "[TrustAccount: " << account.name << ": " << account.balance << ", " << account.interest << "%, " << account.def_bonus << " deposit bonus, " << (3 - account.limit) << " withdrawals remaining]";
    return out;
}

Acctools is the part I use to facilitate displaying the code and testing it out. It just takes a vector of Account (and its derivatives) objects and mass-deposits/mass-withdraws/displays-all.

Acctools.h:

#ifndef _ACCTOOLS_H_
#define _ACCTOOLS_H_
#include <vector>
#include <string>
#include <iostream>
#include "Account.h"
#include "SavingsAccount.h"
#include "CheckingAccount.h"
#include "TrustAccount.h"

// Accounts

void display(const std::vector<Account>& accounts);
void deposit(const std::vector<Account>& accounts, double balance);
void withdraw(const std::vector<Account>& accounts, double balance);

// SavingsAccounts

void display(const std::vector<SavingsAccount>& accounts);
void deposit(const std::vector<SavingsAccount>& accounts, double balance);
void withdraw(const std::vector<SavingsAccount>& accounts, double balance);

// CheckingAccounts

void display(const std::vector<CheckingAccount>& accounts);
void deposit(const std::vector<CheckingAccount>& accounts, double balance);
void withdraw(const std::vector<CheckingAccount>& accounts, double balance);

// TrustAccounts

void display(const std::vector<TrustAccount>& accounts);
void deposit(const std::vector<TrustAccount>& accounts, double balance);
void withdraw(const std::vector<TrustAccount>& accounts, double balance);

#endif // _ACCTOOLS_H_

Acctools.cpp:

#include "Acctools.h"
#include <vector>
#include <string>
#include <iostream>
#include "Account.h"
#include "SavingsAccount.h"
#include "CheckingAccount.h"
#include "TrustAccount.h"

// Accounts
void display(const std::vector<Account>& accounts) {
    std::cout << "\n===Accounts========================================" << '\n';
    for (const auto& acc : accounts)
        std::cout << acc << '\n';
}

void deposit(std::vector<Account>& accounts, double amount) {
    std::cout << "\n===Depositing to Accounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.deposit(amount))
            std::cout << "Deposited " << amount << " to " << acc << '\n';
        else
            std::cout << "Failed deposit of  " << amount << " to " << acc << '\n';
}

void withdraw(std::vector<Account>& accounts, double amount) {
    std::cout << "\n===Withdrawing from Accounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.withdraw(amount))
            std::cout << "Withdrawn " << amount << " from " << acc << '\n';
        else
            std::cout << "Failed withdrawal of " << amount << " from " << acc << '\n';
}

// Savings Accounts

void display(const std::vector<SavingsAccount>& accounts) {
    std::cout << "\n===SavingsAccounts========================================" << '\n';
    for (const auto& acc : accounts)
        std::cout << acc << '\n';
}

void deposit(std::vector<SavingsAccount>& accounts, double amount) {
    std::cout << "\n===Depositing to SavingsAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.deposit(amount))
            std::cout << "Deposited " << amount << " to " << acc << '\n';
        else
            std::cout << "Failed deposit of  " << amount << " to " << acc << '\n';
}

void withdraw(std::vector<SavingsAccount>& accounts, double amount) {
    std::cout << "\n===Withdrawing from SavingsAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.withdraw(amount))
            std::cout << "Withdrawn " << amount << " from " << acc << '\n';
        else
            std::cout << "Failed withdrawal of " << amount << " from " << acc << '\n';
}

// Checking Accounts

void display(const std::vector<CheckingAccount>& accounts) {
    std::cout << "\n===CheckingAccounts========================================" << '\n';
    for (const auto& acc : accounts)
        std::cout << acc << '\n';
}

void deposit(std::vector<CheckingAccount>& accounts, double amount) {
    std::cout << "\n===Depositing to CheckingAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.deposit(amount))
            std::cout << "Deposited " << amount << " to " << acc << '\n';
        else
            std::cout << "Failed deposit of  " << amount << " to " << acc << '\n';
}

void withdraw(std::vector<CheckingAccount>& accounts, double amount) {
    std::cout << "\n===Withdrawing from CheckingAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.withdraw(amount))
            std::cout << "Withdrawn " << amount << " from " << acc << '\n';
        else
            std::cout << "Failed withdrawal of " << amount << " from " << acc << '\n';
}

// Trust Accounts

void display(const std::vector<TrustAccount>& accounts) {
    std::cout << "\n===TrustAccounts========================================" << '\n';
    for (const auto& acc : accounts)
        std::cout << acc << '\n';
}

void deposit(std::vector<TrustAccount>& accounts, double amount) {
    std::cout << "\n===Depositing to TrustAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.deposit(amount))
            std::cout << "Deposited " << amount << " to " << acc << '\n';
        else
            std::cout << "Failed deposit of  " << amount << " to " << acc << '\n';
}

void withdraw(std::vector<TrustAccount>& accounts, double amount) {
    std::cout << "\n===Withdrawing from TrustAccounts========================================" << '\n';
    for (auto& acc : accounts)
        if (acc.withdraw(amount))
            std::cout << "Withdrawn " << amount << " from " << acc << '\n';
        else
            std::cout << "Failed withdrawal of " << amount << " from " << acc << '\n';
}

Finally, the main:

#include <iostream>
#include <string>
#include <vector>
#include "Acctools.h"
#include "Account.h"
#include "SavingsAccount.h"
#include "CheckingAccount.h"
#include "TrustAccount.h"


int main() {

    //////////////////////////////////////////////////// ACCOUNTS

    std::vector<Account> accounts;

    accounts.push_back(Account{ "Cata", 2000 });
    accounts.push_back(Account{ "Pernea", 0 });
    accounts.push_back(Account{ "Razvi", 4000 });

    display(accounts);

    deposit(accounts, 1000);

    display(accounts);

    withdraw(accounts, 3000);

    display(accounts);


    //////////////////////////////////////////////////// SAVINGS ACCOUNTS

    std::vector<SavingsAccount> savingsaccounts;

    savingsaccounts.push_back(SavingsAccount{ "Sapokee", 2000, 5.0 });
    savingsaccounts.push_back(SavingsAccount{ "Bernea", 0, 200.0 });
    savingsaccounts.push_back(SavingsAccount{ "Ravi", 4000, 1.0 });

    display(savingsaccounts);

    deposit(savingsaccounts, 1000);

    display(savingsaccounts);

    withdraw(savingsaccounts, 3000);

    display(savingsaccounts);

    //////////////////////////////////////////////////// CHECKING ACCOUNTS

    std::vector<CheckingAccount> checkingaccounts;

    checkingaccounts.push_back(CheckingAccount{ "Sapok", 2000 });
    checkingaccounts.push_back(CheckingAccount{ "Alex Bernea", 0 });
    checkingaccounts.push_back(CheckingAccount{ "Ravioli", 4000});

    display(checkingaccounts);

    deposit(checkingaccounts, 1000);

    display(checkingaccounts);

    withdraw(checkingaccounts, 3000);

    display(checkingaccounts);

    //////////////////////////////////////////////////// TRUST ACCOUNTS

    std::vector<TrustAccount> trustaccounts;

    trustaccounts.push_back(TrustAccount{ "Sapokee", 2000, 5.0 });
    trustaccounts.push_back(TrustAccount{ "Bernea", 0, 1.0 });
    trustaccounts.push_back(TrustAccount{ "Ravi", 4000, 1.0 });

    display(trustaccounts);

    deposit(trustaccounts, 5000);

    display(trustaccounts);

    withdraw(trustaccounts, 3000);

    display(trustaccounts);

    withdraw(trustaccounts, 100);

    display(trustaccounts);

    withdraw(trustaccounts, 100);

    display(trustaccounts);

    withdraw(trustaccounts, 100);

    display(trustaccounts);

    withdraw(trustaccounts, 100);

    display(trustaccounts);
}

Post answer edit:

Here's the better TrustAccount initialization:

private:
    // ... all other default values
    static constexpr int def_withdrawals = 0;
protected:
    int withdrawals; // changed the name to be more intuitive
public:
    TrustAccount(std::string name = def_name, double balance = def_balance, double interest = def_interest); // removed withdrawals from here

TrustAccount::TrustAccount(std::string name, double balance, double interest)
    : SavingsAccount(name, balance, interest), withdrawals{ def_withdrawals } {}

CodePudding user response:

Your declarations of the deposit and withdraw overloads in Acctools.h have const on the std::vector of the account type.

The fix is to remove const so that the declarations matches the definitions in Acctools.cpp:

#ifndef _ACCTOOLS_H_
#define _ACCTOOLS_H_
#include <vector>
#include <string>
#include <iostream>
#include "Account.h"
#include "SavingsAccount.h"
#include "CheckingAccount.h"
#include "TrustAccount.h"

// Accounts

void display(const std::vector<Account>& accounts);
void deposit(std::vector<Account>& accounts, double balance);
void withdraw(std::vector<Account>& accounts, double balance);

// SavingsAccounts

void display(const std::vector<SavingsAccount>& accounts);
void deposit(std::vector<SavingsAccount>& accounts, double balance);
void withdraw(std::vector<SavingsAccount>& accounts, double balance);

// CheckingAccounts

void display(const std::vector<CheckingAccount>& accounts);
void deposit(std::vector<CheckingAccount>& accounts, double balance);
void withdraw(std::vector<CheckingAccount>& accounts, double balance);

// TrustAccounts

void display(const std::vector<TrustAccount>& accounts);
void deposit(std::vector<TrustAccount>& accounts, double balance);
void withdraw(std::vector<TrustAccount>& accounts, double balance);

#endif // _ACCTOOLS_H_
  • Related