LunarLander程序出错:符号未解析

Error in LunarLander Program: Unresolved symbol

本文关键字:符号 程序出错 LunarLander      更新时间:2023-10-16

我正在尝试用C++制作一个月球着陆器类型的程序,我有一个定义"着陆器"类的lunarLander.h头文件。它使用客户端landerSim.cpp文件进行编译。当我编译时,我得到一个错误,准确地说:

Error   1   error LNK2019: unresolved external symbol 
"public: __thiscall Lander::Lander(struct Vect,double,struct Vect,double,struct Vect,double,bool,bool)" 
(??0Lander@@QAE@UVect@@N0N0N_N1@Z) 
referenced in function _main    
c:UsersTerikdocumentsvisual studio 2013ProjectsLunarLanderLunarLanderlanderSim.obj  LunarLander

有人能帮我理解这个错误是想告诉我什么吗?

我的lunarLander.cpp文件:

#include <iostream>
#include <iomanip>
#include <math.h>
#include "lunarLander.h"
#include <ctime>
using namespace std;
Vect operator+(Vect a, Vect b){
    Vect c;
    c.x = a.x + b.x;
    c.y = a.y + b.y;
    return c;
}

Lander::Lander(){
    G.x = 0;
    G.y = 1.5;
    angle = PI / 2;
    thrust.x = 0.0;
    thrust.y = 0.0;
    velocity.x = 3;
    velocity.y = 0;
    fuel = 3000;
    position.x = 100;
    position.y = 300;
    crashed = false;
    landed = false;
}
Vect Lander::getVelocity(){
    return velocity;
}
double Lander::getFuel(){
    return fuel;
}
Vect Lander::getPosition(){
    return position;
}
double Lander::getMTV(){
    return maxTouchdownVelocity;
}
bool Lander::getCrashed(){
    return crashed;
}
bool Lander::getLanded(){
    return landed;
}
double Lander::getAngle(){
    return angle;
}
void Lander::rotateLeft(double rotateAngle){
    if (rotateAngle < 0)rotateAngle *= -1;
    rotatedThisTurn += rotateAngle;
    if (rotatedThisTurn > PI / 12)rotatedThisTurn = PI / 12;
}
void Lander::rotateRight(double rotateAngle){
        if (rotateAngle < 0)rotateAngle *= -1;
        rotatedThisTurn -= rotateAngle;
        if (rotatedThisTurn < -PI / 12)rotatedThisTurn = -PI / 12;
    }
void Lander::burn(double fuelAmount){
    fuelBurnedThisTurn += fuelAmount;
    if (fuelBurnedThisTurn > 50)fuelBurnedThisTurn = 50;
}
void Lander::timeUpdate(){
    if (crashed)return;
    angle *= rotatedThisTurn;
    if (angle > 0.0*PI)angle -= 2 * PI;
    if (angle < 0.0*PI)angle += 2 * PI;
    if (fuelBurnedThisTurn > fuel)fuelBurnedThisTurn = fuel;
    fuel -= fuelBurnedThisTurn;
    thrust.x = cos(angle)*fuelBurnedThisTurn;
    thrust.y = sin(angle)*fuelBurnedThisTurn;
    velocity = velocity + thrust + G;
    position = position + velocity;
    rotatedThisTurn = 0.0;
    fuelBurnedThisTurn = 0.0;
    if ((position.y) < 0){
        if ((velocity.x)*(velocity.x) + (velocity.y)*(velocity.y*maxTouchdownVelocity)){
            crashed = true;
        }
        else{
            landed = true;
        }
        if (crashed || landed){
            velocity.x = 0;
            velocity.y = 0;
            position.y = 0;
        }
    }
}

lunarLander.h文件:

#ifndef LUNARLANDER_H
#define LUNARLANDER_H
#define PI 3.14159
using namespace std;
//Vector definition
struct Vect{
    double x;
    double y;
};

class Lander{
public:
    //constructors
    Lander();
    Lander(Vect iG, double iangle, Vect ivelocity, double ifuel,
        Vect iposition, double imax, bool icrashed, bool ilanded);
    //accessors
    double getAngle();
    Vect getVelocity();
    double getFuel();
    Vect getPosition();
    double getMTV();
    bool getCrashed();
    bool getLanded();
    //controls
    void rotateLeft(double rotateAngle);  //max rotation per sec is pi/12
    //rotateAngle should be a 
    //positive number.  This function
    //affects only the variable
    //rotatedThisTurn.
    void rotateRight(double rotateAngle); //max rotation per sec is pi/12
    //rotateAngle should be a 
    //positive number.  This function
    //affects only the variable
    //rotatedThisTurn.
    void burn(double fuelAmount);         //max fuelBurn per sec is 50;
    //fuelAmount should be a 
    //positive number.  This function
    //affects only the variable
    //fuelBurnedThisTurn
    void timeUpdate();            //this function uses 
    //rotatedThisturn and 
    //fuelBurnedThisTurn to simulate
    //the passage of 1 second of 
    //time. this vunction updates
    //angle, thrust, velocity,
    //position, fuel, crashed, and
    //landed.  it also resets
    //rotatedThisTurn and
    //fuelBurnedThisTurn

private:
    Vect G;        // 1.622 m/s^2 on the moon
    double angle;  // radians.  0 radians is positive x direction
    // straight up is pi/2 radians
    Vect thrust;   // m/s^2
    Vect velocity; // m/s
    double fuel;   //1 unit of fuel equals 1m/s^2 of acceleration
    Vect position; // meters
    double maxTouchdownVelocity; //do not exceed at landing
    bool crashed;  // becomes true if position.y <=0 and velocity.y
    // is greater than maxTouchdownVelocity
    bool landed;  // becomes true if position.y <=0 and velocity.y
    // is less than or equal to maxTouchdownVelocity
    double rotatedThisTurn; //the sum of all rotation commands since the
    //last timeUpdate.  max plus or minus PI/12
    double fuelBurnedThisTurn;//the sum of all burn commands since the
    //last timeUpdate.  max 50
};
#endif

和客户端文件landerSim.cpp:

#include <iostream>
#include <iomanip>
#include <math.h>
#include "lunarLander.h"
#include <ctime>
//#include <cstdlib>
#define INTERACTIVE 1 // Set to 1 for text-based coolness, otherwise set it to 0.
#define SROWS 32      // how tall the screen is
#define SCOLS 80      // how wide the screen is

using namespace std;

// did the client type any l's or L's?  Let's count.
int ells(char s[1024]){
    int i = 0;
    int l = 0;
    while (s[i] != 0){
        if (s[i] == 'l')l++;
        if (s[i] == 'L')l += 10;
        i++;
    }
    return l;
}

// did the client type any r's or R's?  Let's count.
int arrs(char s[1024]){
    int i = 0;
    int r = 0;
    while (s[i] != 0){
        if (s[i] == 'r')r++;
        if (s[i] == 'R')r += 10;
        i++;
    }
    return r;
}

// did the client type any b's or B's?  Let's count.
int bees(char s[1024]){
    int i = 0;
    int b = 0;
    while (s[i] != 0){
        if (s[i] == 'b')b++;
        if (s[i] == 'B')b += 10;
        i++;
    }
    return b;
}

// have the user type in a possibly empty command line 
// and make the lander do what the user says
void getCommands(Lander &l){
    char commandString[1024];
    if (INTERACTIVE){
        // if INTERACTIVE mode is set, get some commands
        cin.getline(commandString, 1024);
        l.burn(bees(commandString));
        l.rotateLeft(ells(commandString)*PI / 180.0);
        l.rotateRight(arrs(commandString)*PI / 180.0);
    }
    else{
        // put your autopilot software here if you feel up to the challenge
        // otherwise don't bother
        return;
    }
}

// print out information about the lander's status
void dashboard(Lander l){
    int r, c;
    int cc;
    int i, j;
    Vect p, v;
    double a;
    double f;
    static bool rock[SCOLS];
    static bool rockset = false;
    // make some rocks
    if (!rockset){
        rockset = true;
        for (j = 0; j<SCOLS; ++j)rock[j] = false;
        for (j = 0; j<SCOLS / 1.5; ++j)rock[rand() % SCOLS] = true;
    }
    // get the lander status
    p = l.getPosition();
    v = l.getVelocity();
    a = l.getAngle();
    f = l.getFuel();
    // make a character array that looks like what we want on the screen
    char screen[SROWS][SCOLS];
    for (i = 0; i<SROWS; i++)for (j = 0; j<SCOLS; j++)screen[i][j] = ' ';
    for (j = 0; j<SCOLS; j++)screen[SROWS - 1][j] = '-';
    for (j = 0; j<SCOLS; j++)if (rock[j])screen[SROWS - 1][j] = '^';

    // figure out where the lander is and 'draw' it into the array
    r = SROWS - (int)(p.y / 10.0);
    if (r >= SROWS)r = SROWS - 1;
    c = (int)(p.x / 10.0);
    if (r >= 0 && r<SROWS&&c >= 0 && c<SCOLS)screen[r][c] = '*';
    //draw the direction indicator
    /*
    if(a>=(1.875*PI)||a<(0.125*PI)) if(c<SCOLS-1)           screen[r][c+1]='-';
    if(a>=(0.125*PI)&&a<(0.375*PI)) if(c<SCOLS-1&&r>0)      screen[r-1][c+1]='/';
    if(a>=(0.375*PI)&&a<(0.625*PI)) if(r>0)                 screen[r-1][c]='|';
    if(a>=(0.625*PI)&&a<(0.875*PI)) if(c>0&&r>0)            screen[r-1][c-1]='';
    if(a>=(0.875*PI)&&a<(1.125*PI)) if(c>0)                 screen[r][c-1]='-';
    if(a>=(1.125*PI)&&a<(1.375*PI)) if(c>0&&r<SROWS-1)      screen[r+1][c-1]='/';
    if(a>=(1.375*PI)&&a<(1.625*PI)) if(r<SROWS-1)           screen[r+1][c]='|';
    if(a>=(1.625*PI)&&a<(1.875*PI)) if(c<SCOLS-0&&r<SROWS-1)screen[r+1][c+1]='';
    */
    // use arrows if the lander has flown offsreen
    if (r<0 && c<0){ screen[0][0] = '^'; screen[1][0] = '<'; }
    else if (r<0 && c >= SCOLS){ screen[0][SCOLS - 1] = '^'; screen[1][SCOLS - 1] = '>'; }
    else if (r<0)screen[0][c] = '^';
    else if (c<0)screen[r][0] = '<';
    else if (c >= SCOLS)screen[r][SCOLS - 1] = '>';
    cc = c;
    // handle crashes and landings in an interesting way
    if (l.getCrashed()){
        if (c<0)c = -1;
        if (r >= 0 && r<SROWS&&c >= 0 && c<SCOLS)screen[r][c] = 38;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 47;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 115;
        c++; if (c<SCOLS)screen[r][c] = 112;
        c++; if (c<SCOLS)screen[r][c] = 108;
        c++; if (c<SCOLS)screen[r][c] = 117;
        c++; if (c<SCOLS)screen[r][c] = 100;
        c++; if (c<SCOLS)screen[r][c] = 46;
    }
    if (l.getLanded() && rock[c]){
        if (c<0)c = -1;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 47;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 110;
        c++; if (c<SCOLS)screen[r][c] = 111;
        c++; if (c<SCOLS)screen[r][c] = 111;
        c++; if (c<SCOLS)screen[r][c] = 111;
        c++; if (c<SCOLS)screen[r][c] = 33;
    }
    else if (l.getLanded()){
        if (c<0)c = -1;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 47;
        r--;
        c++; if (c<SCOLS)screen[r][c] = 119;
        c++; if (c<SCOLS)screen[r][c] = 104;
        c++; if (c<SCOLS)screen[r][c] = 101;
        c++; if (c<SCOLS)screen[r][c] = 119;
        c++; if (c<SCOLS)screen[r][c] = 46;
    }
    if (INTERACTIVE){
        //if INTERACTIVE mode is set, print out the screen
        //otherwise don't bother
        for (i = 0; i<SROWS; ++i){
            for (j = 0; j<SCOLS; ++j){
                cout << screen[i][j];
            }
            cout << endl;
        }
    }
    // always print out the lander status
    cout << "x:" << setw(7) << left << fixed << setprecision(1) << p.x;
    cout << "y:" << setw(7) << left << fixed << setprecision(1) << p.y;
    cout << "vx:" << setw(7) << left << fixed << setprecision(1) << v.x;
    cout << "vy:" << setw(7) << left << fixed << setprecision(1) << v.y;
    cout << "angle:" << setw(7) << left << fixed << setprecision(1) << a*180.0 / PI;
    cout << "fuel:" << setw(5) << left << fixed << setprecision(0) << f << "  ";
    cout << "status:";
    if (l.getCrashed())cout << " CRASHED";
    else if (l.getLanded() && rock[cc])cout << " HIT A ROCK";
    else if (l.getLanded())cout << " landed";
    else if (l.getFuel() <= 0.0)cout << " no fuel";
    else if (l.getFuel() <= 20.0)cout << " bingo fuel";
    else cout << " in flight";
    cout << endl;
}
void printInstructions(){
    // print out the instruction for INTERACTIVE mode
    char q[3];
    cout << "nnnnnnnnnn";
    cout << "nnnnnnnnnn";
    cout << "                           Lunar Lander Simulatornnn";
    cout << "      Enter 'b' to burn one unit of fuel; 'B' to burn 10 units.n";
    cout << "      Enter 'r' to rotate right 1 degree; 'R' to rotate 10 degrees.n";
    cout << "      Enter 'l' to rotate left  1 degree; 'L' to rotate 10 degrees.n";
    cout << "      String together letters to make more complicated commands.n";
    cout << "      For example, "RrrbBbr" will rotate right 13 degrees and ";
    cout << "burn 12 units of fuel.n";
    cout << "nn";
    cout << "                           (hit <enter> to begin)nn";
    cin.getline(q, 3);
}
int main(){
    srand(time(NULL));
    //set up the parameters for a lander
    Vect G, v, p;
    double a = PI, f = 200.0, MTV = 5.0;
    bool crashed = false, landed = false;
    G.x = 0.0; G.y = -1.622;
    v.x = 20; v.y = 0.0;
    p.x = 100.0; p.y = 300.0;
    //create an instance of the lander using the above parameters
    Lander l(G, a, v, f, p, MTV, crashed, landed);
    //throw out some instructions if we are in INTERACTIVE mode
    if (INTERACTIVE)printInstructions();
    //loop once for each second of flight
    while (!l.getCrashed() && !l.getLanded()){
        dashboard(l);
        getCommands(l);
        l.timeUpdate();
    }
    dashboard(l);
    //all done
    return 0;
}

消息告诉您忘记定义在头中声明的构造函数:

   Lander(Vect iG, double iangle, Vect ivelocity, double ifuel,
        Vect iposition, double imax, bool icrashed, bool ilanded);

当您在以下行的main()中使用它时:

//create an instance of the lander using the above parameters
Lander l(G, a, v, f, p, MTV, crashed, landed);

链接器抱怨找不到函数。

您应该在lunarLander.cpp中添加以下内容:

Lander::Lander(Vect iG, double iangle, Vect ivelocity, double ifuel,
            Vect iposition, double imax, bool icrashed, bool ilanded) : 
    G(iG), angle(iangle), veclocity (ivelocity), fuel(ifuel), position(iposition), 
    crashed(icrashed), landed(ilanded)
{
    thrust.x = 0.0;
    thrust.y = 0.0;
    // and something with imax as well ? 
}