any idea what i am doing wrong?

Error 3 error LNK2001: unresolved external symbol "private: static float SavingsAccount::annualInterestRate" (?annualInterestRate@SavingsAccount@@0MA) Savings.obj

SavingsAccount.h

#ifndef SAVINGSACCOUNT1_H
#define SAVINGSACCOUNT1_H

using namespace std;

class SavingsAccount 
{
private:
    static float annualInterestRate;
    float savingsBalance;
public:
    SavingsAccount()
    {
      annualInterestRate = 0.03;
      savingsBalance= 2000;
    }
    float calculateMonthlyInterest()
    {
        float subtotal = 0;
        float monthlyint = 0;
        subtotal = savingsBalance * annualInterestRate;
        monthlyint = subtotal / 12;
        savingsBalance = monthlyint + savingsBalance;
        return savingsBalance;
    }
    static void modifyInterestRate()
    {
        annualInterestRate=.04;
    }
    void printSavingsBalance()
    {
        cout << "Your balance is: $" << savingsBalance << endl;
    }
};
#endif

Savings.cpp

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

using namespace std;

int main()
{
SavingsAccount saver1;        //instantiate saver1;
SavingsAccount saver2;        //instantiate saver2;

saver1.printSavingsBalance();
cout << "Interest of Month #1" << saver1.calculateMonthlyInterest() << endl;
saver1.modifyInterestRate();
cout << "Interest of Month #2" << saver1.calculateMonthlyInterest() << endl;

return 0;
}

any help would be great

:o

Dani AI

Generated

The linker error LNK2001 in this thread is caused by the class-level static declaration not providing storage. Declaring static float annualInterestRate; inside the class only names the member; the linker still needs exactly one out-of-class definition that allocates storage. Assigning to that static inside the constructor does not create that definition, so references to the symbol remain unresolved. This is the practical reason behind ’s comment.

Two practical fixes to choose from:

  • For modern compilers (C++17 and later), give the static member an in-class definition by marking it inline. That both declares and defines the object so no extra line in a .cpp file is required. Example (C++17+):

    class SavingsAccount {
    private:
        inline static float annualInterestRate = 0.03f; // single definition, C++17+
        float savingsBalance = 2000.0f;
        ...
    };
  • For pre-C++17 toolchains, provide a single definition in one .cpp translation unit to allocate storage and optionally set the default value (the linker error goes away once that definition exists).

A few additional best practices tied to replies already here: avoid using namespace std; in headers and either include <iostream> in the header if it truly owns printing, or move output functions into the implementation file. Because a static rate is shared by all instances, setting it inside the constructor will overwrite the shared value each time an object is created — if the rate should vary per account, follow ’s suggestion and make it a non-static member. Finally, be aware of static initialization order across translation units; inline statics or function-local statics are safer patterns for initialization-order concerns, and as noted, statics are zero-initialized by default but still require a definition for linking.

Recommended Answers

All 5 Replies

Why did you make it static?

It makes ALL the accounts have the same annual interest rate, and that's simply not true in the real world.

You need this just before your main

float SavingsAccount::annualInterestRate = 0;

> using namespace std;
Putting this in a header file is very bad form.
Anyone who includes the file will get the whole namespace whether they like it or not.

commented: very smart +1

I had to make this static as if it were a fixed interest rate that a person is locked into. What is the logic behind using

float SavingsAccount::annualInterestRate = 0;
right before my main? I see that you are setting annualInterestRate to zero, but why does this need to be done? Afterall, I have made annualInterestRate .03 in the default constructor.

Thank you s.o.s.

~hoosier23

Try out something like:

#ifndef SAVINGSACCOUNT1_H
#define SAVINGSACCOUNT1_H

class SavingsAccount 
{
private:
    float annualInterestRate;
    float savingsBalance;
    
public:
    SavingsAccount()
    {
      annualInterestRate = 0;
      savingsBalance= 0;
    }
    
    SavingsAccount (float my_interest_rate, float my_savings_balance)
    {
        annualInterestRate = my_interest_rate ;
        savingsBalance = my_savings_balance ; 
    }
    
    float calculateMonthlyInterest()
    {
        float subtotal = 0;
        float monthlyint = 0;
        subtotal = savingsBalance * annualInterestRate;
        monthlyint = subtotal / 12;
        savingsBalance = monthlyint + savingsBalance;
        return savingsBalance;
    }
    
    void setInterestRate (float my_interest_rate)
    {
        annualInterestRate = my_interest_rate ;
    }
    void printSavingsBalance()
    {
        cout << "Your balance is: $" << savingsBalance << endl;
    }
};
#endif
#include <iostream> 
#include "SavingsAccount.h"
using namespace std;

int main()
{
    SavingsAccount saver1 (1, 2) ;        //instantiate saver1;
    SavingsAccount saver2 (2, 3) ;        //instantiate saver2;

    saver1.printSavingsBalance();
    cout << "Interest of Month #1" << saver1.calculateMonthlyInterest() << endl;
    saver1.setInterestRate (4);
    cout << "Interest of Month #2" << saver1.calculateMonthlyInterest() << endl;
    return 0;
}

Hope it helped, bye.

What is the logic behind using

float SavingsAccount::annualInterestRate = 0;
right before my main? I see that you are setting annualInterestRate to zero, but why does this need to be done? Afterall, I have made annualInterestRate .03 in the default constructor.

I believe static variables will be automatically initialized to zero or with their default constructor (and someone correct me if I'm wrong) if you don't specify, so it shouldn't be necessary. It's still often better to be explicit, though.

And don't assume that annualInterestRate will have a value of 0.3 whenever you choose to use it (if it's static, that is, since it can be used before the class constructor is called)

> Afterall, I have made annualInterestRate .03 in the default constructor.
You made it static, so there is only ever ONE instance of it.

You could change the assignment I posted to make it read .03 and remove the assignment from your constructor and it should still do the same thing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.