Why am I getting Unresolved external when using Static in a class

I have this Main program that calls a class in a header file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "SavingsAccount.h"
int main()
{       
    // Since this assignment purpose is how to set the class, no calculation will be done to determine if the interest
    // for the month has already been calculated or not. It is not a part of the assignment. The boolean 
    // "monthInterestnotYetEntered" is TRUE if the interest for the month is not yet added and FALSE if already added. 
    bool monthInterestnotYetEntered = true;

    // Test of negative account balance
    TESTONLY::SavingsAccount myAccount(-24.50);
    std::cout << "The amount in the account is : " << myAccount.getSavingsAccount() << '\n';

    // Test of negative interest rate
    myAccount.setAnnualInterestRate(5.50);
    //std::cout << "The annual interest rate is : " << myAccount.getAnnualInterest() << '\n';
    std::cin.get();
    return 0;
}


This is the Header File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//This is from date.h header file
#include <iostream>  

#ifndef SAVINGSACCOUNT_H
#define SAVINGSACCOUNT_H
namespace TESTONLY
{
    class SavingsAccount
    { 
    public:
        // Constructor of the SavingsAccount, the class is initialize to the value declared in the valid parameter
        // If the parameter is a negative value the initial balance is set to zero
        SavingsAccount (double initialBalance) 
        {
             if (initialBalance < 0) 
                 savingsBalance = 0; 
             else
                 savingsBalance = initialBalance;
        }

        //Destructor of the class 
        ~SavingsAccount()
        {
            std::cout << "end of the program";
        }

        // return the private member savingsBalance  and check data if is positive
        // if the savingsBalance is negative a value of Zero is returned
        double getSavingsAccount() const
        { 
             if (savingsBalance < 0) 
                 return 0; 
             else
                 return savingsBalance;
             
        }

        // Calculate the monthly interest rate
        // The program calling this method will decide if the interest for the month has already been applied.
        // this method will assume that when it is called all it does is calculate the additional interest
        double applyMonthlyInterest() 
        { 
            if (annualInterestRate > 0)
                return (savingsBalance += (savingsBalance * annualInterestRate/12));
            else
                return savingsBalance;
        }

        // The Annual interest rate is set if the parameter is greater than zero
        // if the parameter is negative the interest is set to Zero
        void setAnnualInterestRate(double newInterestRate)  
        {
             if (newInterestRate < 0)
             {
                 std::cerr << "New Interest rate unacceptable";
                 annualInterestRate = 0;
             }
             else
                 annualInterestRate = newInterestRate;
        }

        double getAnnualInterest() const
        {
            return annualInterestRate;
        }

    private:
        double savingsBalance;
        double annualInterestRate;
    }; 
}
#endif 


This code works fine the way it is, but the program specification requires that the "annualInterestRate" in the Private section of the class be declared STATIC.
so I changed it to " static double annualInterestRate".

As soon as I do that I get an error in compilation "Unresolved external", and I do not know why.

can somebody tell me what I am doing wrong?
A "static" data member in a class definition is a declaration. You need to have a definition of the variable somewhere. Usually, that would be in the cpp file associated with that particular header.

At file scope in the cpp file you would need:

double TESTONLY::SavingsAccount::annualInterestRate /* = defaultAmount */ ;
Ok, I read the book and you are right so I declared in my main .cpp this
TESTONLY::SavingsAccount::annualInterestRate = -5.50;

Now I am getting a redefinition error.
Don't forget the type specifier.

double TESTONLY::SavingsAccount::annualInterestRate /* = defaultAmount */ ;
Cire: My apology, I was in a hurry to respond in case you were still awake but I did include the type. Actually this is what I have now: I replaced the namespace TESTONLY by JuanSanchez just to satisfy the specification but that should not be an issue. You will see that I have 2 static definition one is the last public method..... static void setAnnualInterestRate(double newInterestRate) and the other one is a private member .... static double annualInterestRate; and both are causing a compiler error..


This is the main with the declaration of the static variable as you have suggested and I read the book and it is telling me the same thing. I must be doing interpreting the book wrong. You on the other hand has a very precise instruction.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#include "SavingsAccount.h"
int main()
{       
    // Since this assignment purpose is how to set the class, no calculation will be done to determine if the interest
    // for the month has already been calculated or not. It is not a part of the assignment. The boolean 
    // "monthInterestnotYetEntered" is TRUE if the interest for the month is not yet added and FALSE if already added. 
    bool monthInterestnotYetEntered = true; 
    double JuanSanchez::SavingsAccount::annualInterestRate;

    // Test of negative account balance
    JuanSanchez::SavingsAccount JuansAccount(-24.50);
    std::cout << "The amount in the account is : " << JuansAccount.getSavingsAccount();

    // Test of negative interest rate 
    JuanSanchez::SavingsAccount.setAnnualInterestRate(-5.50);
    std::cin.get();
    return 0;
}



This is the header file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//This is from date.h header file
#include <iostream>  

#ifndef SAVINGSACCOUNT_H
#define SAVINGSACCOUNT_H
namespace JuanSanchez
{
    class SavingsAccount
    { 
    public:
        // Constructor of the SavingsAccount, the class is initialize to the value declared in the valid parameter
        // If the parameter is a negative value the initial balance is set to zero
        SavingsAccount (double initialBalance) 
        {
             if (initialBalance < 0) 
                 savingsBalance = 0; 
             else
                 savingsBalance = initialBalance;
        }

        //Destructor of the class 
        ~SavingsAccount()
        {
            std::cout << "end of the program";
        }

        // return the private member savingsBalance  and check data if is positive
        // if the savingsBalance is negative a value of Zero is returned
        double getSavingsAccount() const
        { 
             if (savingsBalance < 0) 
                 return 0; 
             else
                 return savingsBalance;
             
        }

        // Calculate the monthly interest rate
        // The program calling this method will decide if the interest for the month has already been applied.
        // this method will assume that when it is called all it does is calculate the additional interest
        double applyMonthlyInterest() 
        { 
            if (annualInterestRate > 0)
                return (savingsBalance += (savingsBalance * annualInterestRate/12));
            else
                return savingsBalance;
        }

        // The Annual interest rate is set if the parameter is greater than zero
        // if the parameter is negative the interest is set to Zero
        static void setAnnualInterestRate(double newInterestRate)  
        {
             if (newInterestRate < 0)
             {
                 std::cerr << "New Interest rate unacceptable";
                 JuanSanchez::SavingsAccount::annualInterestRate = 0; 
             }
             else
                 JuanSanchez::SavingsAccount::annualInterestRate = newInterestRate;
        }
        
    private:
        double savingsBalance;
        static double annualInterestRate;
    }; 
}
#endif 


And these are the compiler errors when I added the declaration of the static variable in the main

Error 2 error C2086: 'double JuanSanchez::SavingsAccount::annualInterestRate' : redefinition c:\eds directory\programming lessons\c and c++ programming\class c3\c3_assignment3_final\savingsaccount.cpp 21 1 C3_Assignment3_FINAL
Error 3 error C2143: syntax error : missing ';' before '.' c:\eds directory\programming lessons\c and c++ programming\class c3\c3_assignment3_final\savingsaccount.cpp 28 1 C3_Assignment3_FINAL
Error 4 error C2143: syntax error : missing ';' before '.' c:\eds directory\programming lessons\c and c++ programming\class c3\c3_assignment3_final\savingsaccount.cpp 28 1 C3_Assignment3_FINAL
Error 1 error C2655: 'JuanSanchez::SavingsAccount::annualInterestRate' : definition or redeclaration illegal in current scope c:\eds directory\programming lessons\c and c++ programming\class c3\c3_assignment3_final\savingsaccount.cpp 21 1 C3_Assignment3_FINAL
5 IntelliSense: member "JuanSanchez::SavingsAccount::annualInterestRate" cannot be defined in the current scope c:\eds directory\programming lessons\c and c++ programming\class c3\c3_assignment3_final\savingsaccount.cpp 21 41 C3_Assignment3_FINAL


Can you please look on my code, it must be something simple because without the Static declaration of the private component of the class the program executes correctly. As soon as I add the type static the compiler starts complaining.
#ifndef ...

should be before any #include
As I mentioned before, the variable must be defined at file scope -- outside of any function. If you try to define it inside of a function, you're giving it a different linkage and storage duration than the variable that was declared in the class definition (in other words you're attempting to redefine the variable.)
closed account (S6k9GNh0)
You don't need to redeclare the variable in implementation, it's already been declared in the header (which you include). You can only declare a variable once.

Herm... I don't remember why but you have to explicitly declare it in implementation like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "test.h"

double JuanSanchez::SavingsAccount::annualInterestRate;

int main()
{       
    // Since this assignment purpose is how to set the class, no calculation will be done to determine if the interest
    // for the month has already been calculated or not. It is not a part of the assignment. The boolean 
    // "monthInterestnotYetEntered" is TRUE if the interest for the month is not yet added and FALSE if already added. 
    bool monthInterestnotYetEntered = true; 

    // Test of negative account balance
    JuanSanchez::SavingsAccount JuansAccount(-24.50);
    std::cout << "The amount in the account is : " << JuansAccount.getSavingsAccount();

    // Test of negative interest rate 
    JuansAccount.setAnnualInterestRate(-5.50);
    std::cin.get();
    return 0;
}


Also, note the change at JuansAccount.setAnnualIntrestRate(-5.50);. It now uses the object you created.
Last edited on
Cire, computerquip,

You are correct, the declaration should be outside the main function.
I went back and read the book again, thinking maybe the book is wrong.

I think I made a mistake.
The sample program was like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//HEADER FILE
myheader.h
class aClass
{
     public: 
            all methods
     private:
            all attributes
            static double myStatic;
};

// THE FIRST .cpp FILE
secondary.cpp 
     #include "myheader.h"

     double aClass::mystatic;  // SO I THINK THIS IS DECLARED OUTSIDE ANY FUNCTION
     afunction1()
     {
           some code;
     }

      afunction2()
     {
           some code;
     }

// THE MAIN .cpp
Main.cpp
{
     some code here;
 }


What do you think I made a mistake I read the sample program incorrectly ?
Topic archived. No new replies allowed.