【问题标题】:Unresolved External Symbol Errors when using header and class definition files使用头文件和类定义文件时未解决的外部符号错误
【发布时间】:2015-01-16 08:07:46
【问题描述】:

我确信我的变量声明和定义到处都是,但这不是重点。对于这个作业,我们得到了一个无法编辑的主 cpp 文件,必须制作一个头文件和类 cpp 文件。我收到未解决的外部符号错误,似乎无法弄清楚。代码如下:

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

和 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
}

这是我得到的错误:

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)

非常感谢任何帮助

【问题讨论】:

  • 展示你如何编译和链接

标签: c++ unresolved-external


【解决方案1】:

首先也是最重要的:在测试任何代码之前不要编写这么多代码。从小而简单的开始,让某些东西完美运行(即使它什么都不做),在有一次,在每一步都进行测试,并且永远不要添加不起作用的代码。

更具体地说,查看您的变量custTax。您在RestaurantCheck.h 中将其声明为静态成员变量,但随后在RestaurantCheck.cpp 中错误地将其定义为全局变量

double custTax = 0;

正确的做法是这样的:

double RestaurantCheck::custTax = 0;

cistTipmenuPricemenuDesc 似乎也有类似的问题。

方法定义——包括构造函数定义——属于源文件(例如RestaurantCheck.cpp),而不是头文件(例如RestaurantCheck.h)。

【讨论】:

  • 不幸的是,教授坚持我们在头文件中定义了方法。无论如何,我按照您的建议将定义移动到源文件中,并且一切似乎都运行良好。感谢您的帮助!
猜你喜欢
  • 2013-06-11
  • 2013-08-07
  • 2011-02-27
  • 2011-06-13
  • 2021-02-04
  • 2011-09-03
  • 2010-11-20
  • 2016-11-26
  • 2013-07-25
相关资源
最近更新 更多