Unresolved External Symbol Errors when using header and class definition files

631 views Asked by At

I'm sure my variable declarations and defintions are all over the place but thats not the point. For this assignment, we were given a main cpp file which we could not edit and have to make a header and class cpp file. I'm getting unresolved external symbol errors and can't seem to figure it out. Here's the code:

main.ccp

#include "stdafx.h"          // Defines external definiton files required
#include <iostream>          // Defines objects and classes used for stream I/O
#include <iomanip>           // Defines output stream manipulators
#include "RestaurantCheck.h"

int main()
{
// Variable Declarations
double taxRate;
double tipRate;


// Display a description of the solution
cout << "PROG-111: Project #8, Version 2 Solution\n\n";

do
{   // Solicit the tax rate, as a percntage, from the User
    cout << "Enter the tax rate, as a %: ";
    cin >> taxRate;
} while (!RestaurantCheck::testTaxRate(taxRate));

do
{   // Solicit the tip, as a percntage, from the User
    cout << "Enter the tip, as a %: ";
    cin >> tipRate;
} while (!RestaurantCheck::testTipRate(tipRate));


// Instantiate a Restuarant Check object
RestaurantCheck order(taxRate, tipRate);

if (!order.placeOrder())
    cout << "\nYou have elected NOT to enter an Order!" << endl;
else
{   // An Order was successfully entered...
    cin.ignore(cin.rdbuf()->in_avail(), '\n');
    cout << "\nPress \"Enter\" when ready for the customer's check: ";
    cin.get();

    // Display the Customer's Check
    order.issueCheck();
}


// This prevents the Visual Studio Console Window from closing during
// debug mode.
// This next statement purges any characters, if any, remaining in the
// Console input buffer, BEFORE "cin.get()" looks for the "new line" character
cin.ignore(cin.rdbuf()->in_avail(), '\n');
cout << "\nPress \"Enter\" to Exit the program: ";
cin.get();

return 0;
}

RestaurantCheck.h

#include <string>
#include "stdafx.h"
class RestaurantCheck
{
private:
static double custTip; //assigned to given tip amount
static double custTax; // assigned to given tax amount
public:
const static int maxNum = 12; // array limiter
const static int userLim = 5; //limits user choices to 5 max
const static double menuPrice[maxNum]; //menu price array
const static std::string menuDesc[maxNum]; //menu description array
double userChoice[userLim]; //array to hold user choices

double calculateTax(); //calculates tax
double calculateTip(); //calculates tip


static bool testTaxRate(double tempTax); //function to test tax
static bool testTipRate(double tempTip); //function to test tip

bool placeOrder(); //function to assign to user order arrays

void presentMenu(); //displays the menu

void issueCheck(); //displays user receipt


RestaurantCheck::RestaurantCheck() //default constructor
{
    custTip = 0.15;
    custTax = 0.065;
}

RestaurantCheck(double taxRate, double tipRate) //user answer constructor
{
    custTax = (taxRate / 100);
    custTip = (tipRate / 100);
}
};

and RestaurantCheck.cpp

#include "stdafx.h"
#include <string>
#include <iostream>
#include "RestaurantCheck.h"
using namespace std;

int orderTotal = 0; //totals the number of items ordered

double custTip = 0;
double custTax = 0;

double subTip; //assigned to calculated tip
double subTax; // assigned to calculated tax

const static int maxNum = 12; // array limiter
const static int userLim = 5; //limits user choices to 5 max

double subtotal; //used in calctip & calctax
double total; //used to display final total
int menuCount; //for loop counters
int orderCount; //for loop counters

double menuPrice[maxNum] =  { 0, 1.25, 4.25, 5.75, 7.95, 6.95, 2.50, 1.95, 4.25, 5.25, 6.25, 0 }; //menu price array
const static std::string menuDesc[maxNum] = {" ", "Eggroll", "Pot Stickers", "Terriyaki Chicken", "Terriyaki Pork",
                                             "Terriyaki Beef", "Wonton Soup", "Egg Drop Soup", "Chicken Fried Rice",
                                             "Pork Fried Rice", "Veggie Fried Rice", "To finish the order choose this option." }; //menu description array
double userChoice[userLim]; //Users array for ordering

bool RestaurantCheck::testTaxRate(double tax) //tax tester return bool 
{
    if (tax >= 0.01 && tax <= 0.12)
    {
        return true;
    } else {
        return false;
    }
    return false;
}

bool RestaurantCheck::testTipRate(double tip) //tip tester return bool
{
    if (tip >= 0.05 && tip <= 0.20)
    {
        return true;
    } else {
        return false;
    }
    return false;
}

void RestaurantCheck::presentMenu() //displays the menu
{
    for (menuCount = 1; menuCount <= maxNum; menuCount++)
    {
        cout << menuCount << ". " << menuDesc[menuCount] << " $" << menuPrice[menuCount];
        if(menuCount % 2 == 0) //makes two objects per line
        {
            cout << endl;
        }
    }
}

bool RestaurantCheck::placeOrder() //prompts user to answer up to 5 choices w/ a SENTINEL value to stop ordering;
{
    presentMenu();
    int input;
    for(orderCount = 0; orderCount <= userLim; orderCount++)
    {
        cout << "Enter order #" << orderCount+1;
        cin >> input;
        switch (input) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
            userChoice[input] = menuPrice[input]; //userchoice is added to array and subtotal is added
            subtotal += menuPrice[input];
            orderTotal++;
            return true;
            break;
        case 11:
            return false;
        //SENTINEL value. Order completes here.
        default:
            return false;
        }
        return false;
    }
    return false;
}

double RestaurantCheck::calculateTax() //caluculates tax
{
    subTax = subtotal * custTax;
    return 0;
}

double RestaurantCheck::calculateTip() //calculates tips
{
    subTip = subtotal * custTip;
    return 0;
}

void RestaurantCheck::issueCheck() //displays items ordered, subtotal, tax, tip, and total
{
    calculateTax();
    calculateTip();
    system("cls");
    cout << "Customer Check" << endl;
    int i; //temp loop counter
    for (i = 1; i <= orderTotal; i++) //displays ordered items
    {
        cout << i << ". " << menuDesc[i] << " $" << menuPrice[i] << endl; 
    }

    total = subtotal + subTax + subTip;
    cout << subtotal;
    cout << subTax;
    cout << subTip; //ALIGN W/ DECIMAL POINTS. 2 DIGITS OF RECISION AFTER THE DECIMAL POINT
    cout << total;
//display subtotal/total/tax/tip
//display userchoice array with limit of ordertotal
}

Here are the errors I am getting:

1>Project7B.obj : error LNK2001: unresolved external symbol "private: static double RestaurantCheck::custTax" (?custTax@RestaurantCheck@@0NA)
1>RestaurantCheck.obj : error LNK2019: unresolved external symbol "private: static double RestaurantCheck::custTax" (?custTax@RestaurantCheck@@0NA) referenced in function "public: void __thiscall std::allocator<char>::construct<char *,char * &>(char * *,char * &)" (??$construct@PADAAPAD@?$allocator@D@std@@QAEXPAPADAAPAD@Z)
1>RestaurantCheck.obj : error LNK2001: unresolved external symbol "public: static double const * const RestaurantCheck::menuPrice" (?menuPrice@RestaurantCheck@@2QBNB)
1>RestaurantCheck.obj : error LNK2001: unresolved external symbol "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const * const RestaurantCheck::menuDesc" (?menuDesc@RestaurantCheck@@2QBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@B)

Any help is very much appreciated

1

There are 1 answers

1
Beta On BEST ANSWER

First and most important: do not write this much code before testing any of it. Start small and simple, get something to work perfectly (even if it does nothing), add complexity a little at a time, test at every step and never add to code that doesn't work.

More specifically, look at your variable custTax. You declare it in in RestaurantCheck.h as a static member variable, but then define it incorrectly in RestaurantCheck.cpp as a global variable

double custTax = 0;

The correct way is like this:

double RestaurantCheck::custTax = 0;

You seem to have similar problems with cistTip, menuPrice and menuDesc.

Method definitions -- including constructor definitions -- belong in the source file (e.g. RestaurantCheck.cpp), not in a header file (e.g. RestaurantCheck.h).