错误LNK2019:未解析的外部符号 - 类别差异

时间:2015-02-12 04:43:39

标签: c++ class linker atom-editor

我在课堂上制作游戏,还没有使用游戏引擎。但它是俄罗斯方块,而且我第一次在课堂上遇到麻烦可能是因为我还不确定C ++中的一切是如何工作的。

它在我的C ++课之前运作良好。我带了一些教授和#39;咨询。我认为问题的建议是我删除了#include "class.cpp"的使用并开始在#include "class.h"中使用src.cpp,类是该特定类的名称。

如果您想知道我是如何编译它的,那么它是通过Visual Studio 2013社区版的编译器实现的。使用来自vsvarsall.bat的cl命令(如果您正在关注手工制作的英雄,那么您已经知道了这一点)。 shell.bat进行编译,run.bat只运行从shell.bat创建的.exe。

我收到此错误:"

  

src.obj src.obj:错误LNK2019:未解析的外部符号" public:   __cdecl tetrimino :: tetrimino(int)" (?? 0tetrimino @@ QEAA @ H @ Z)在函数main

中引用      

src.obj:错误LNK2019:未解析的外部符号" public:__ cdecl   井::井(无效)" (?? 0well @@ QEAA @ XZ)在函数main

中引用      

src.obj:错误LNK2019:未解析的外部符号" public:void   __cdecl well :: AddPieceToWell(类tetrimino)" (?AddPieceToWell @ well @@ QEAAXVtetrimino @@@ Z)在函数中引用   主

     

src.obj:错误LNK2019:未解析的外部符号" public:void   __cdecl well :: DataDump(int)" (?DataDump @ well @@ QEAAXH @ Z)在函数main

中引用      

src.exe:致命错误LNK1120:4个未解析的外部"

我猜测程序不知道cpp在哪里?我不包括课程' cpp代码中的任何其他地方,因为我的proc说只做.h'

我已经查看了有关堆栈溢出的其他类似问题,答案看起来很复杂而且不完全,有些与Visual Studio的混乱有关,但我使用的是Atom而不是视觉解决方案工作室。虽然如果某个地方有帖子,如果有人链接,我会尝试理解它。

来源: src.cpp

/*
    Author: Jesse Coyle
    Program: Wells Glazes!
    Description: Inheritence and Classes extended
    Date: 2/2/2015
*/

#include <iostream>
#include <iomanip>
#include <ctime>
#include <random>

using namespace std;

#include "well.h"
#include "tetrimino.h"

int main()
{
    well WellsGlazes;
    tetrimino TetriminoTestObject;

    WellsGlazes.AddPieceToWell(TetriminoTestObject);

    //WellsGlazes.ClearFullRows();

    WellsGlazes.DataDump(1);

    //system("pause");
    return 0;
}

tetrimino.cpp:

/*
    Author: Jesse Coyle
    Description: Tetrimino class methods
    Date: 1/26/2015
*/

tetrimino::tetrimino(int Type)
{
    static int TimeChanger = 0;

    srand(time(NULL) + TimeChanger++);

    int ARandomInt = rand() % Type;

    SetPosition(0, 0);

    switch(ARandomInt)
    {
    case 0:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 0, 0, 0},
                {1, 1, 1, 1},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 't';
        }
        break;
    case 1:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {1, 0, 0, 0},
                {1, 1, 1, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'b';
        }
        break;
    case 2:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 0, 1, 0},
                {1, 1, 1, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'o';
        }
        break;
    case 3:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 1, 1, 0},
                {0, 1, 1, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'y';
        }
        break;
    case 4:
        {
            // NOTE(Jesse): Does square move when rotated?
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 1, 1, 0},
                {1, 1, 0, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'g';
        }
        break;
    case 5:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 0, 1, 0},
                {1, 1, 1, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'p';
        }
        break;
    case 6:
        {
            int BufferGrid[4][4] =
            {
                {0, 0, 0, 0},
                {0, 1, 0, 0},
                {1, 1, 1, 0},
                {0, 0, 0, 0}
            };

            CopyArray(BufferGrid, Grid);

            Color = 'r';
        }
        break;
    }
}

void
tetrimino::CopyArray(int const Array[][4], int ArrayCopy[][4])
{
    for (int Y = 0;
            Y < 4;
            ++Y)
    {
        for (int X = 0;
                X < 4;
                ++X)
        {
            ArrayCopy[Y][X] = Array[Y][X];
        }
    }
}

void const
tetrimino::PrintArray(int Array[][4])
{
    for (int Y = 0;
            Y < 4;
            ++Y)
    {
        for (int X = 0;
                X < 4;
                ++X)
        {
            cout << Array[Y][X];
        }
        cout << endl;
    }
}

char
tetrimino::GetColor(void)
{
    return Color;
}

position
tetrimino::GetPosition(void)
{
    return Pos;
}

void
tetrimino::GetGrid(int Grid[][4])
{
    for (int X = 0;
             X < 4;
             ++X)
    {
        for (int Y = 0;
             Y < 4;
             ++Y)
        {
            Grid[X][Y] = this->Grid[X][Y];
        }
    }
}

void
tetrimino::SetPosition(position NewPos)
{
    Pos.X = NewPos.X;
    Pos.Y = NewPos.Y;
}

void
tetrimino::SetPosition(int X, int Y)
{
    Pos.X = X;
    Pos.Y = Y;
}

void
tetrimino::RotateClockwise(void)
{
    int ArrayBuffer[4][4];

    //To Mirror the rotated shape correctly
    int Reverse = 3;

    //Rotate and mirror(since rotating mirrors the shape)
    for (int X = 0;
             X < 4;
             ++X)
    {
        for(int Y = 0;
              Y < 4;
              ++Y)
        {
            ArrayBuffer[Y][Reverse] = Grid[X][Y];
        }
        --Reverse;
    }

    for(int X = 0;
             X < 4;
             ++X)
    {
        for(int Y = 0;
                Y < 4;
                ++Y)
        {
            Grid[X][Y] = ArrayBuffer[X][Y];
        }
    }
}

void
tetrimino::RotateCounterClockwise(void)
{
    int ArrayBuffer[4][4];

    //To mirror the rotation/rotate correctly
    int Reverse;

    //Rotate the shape
    for(int X = 0;
            X < 4;
            ++X)
    {
        Reverse = 3;
        for(int Y = 0;
                Y < 4;
                ++Y)
        {
            ArrayBuffer[Reverse][X] = Grid[X][Y];
            --Reverse;
        }
    }

    for(int X = 0;
             X < 4;
             ++X)
    {
        for(int Y = 0;
                Y < 4;
                ++Y)
        {
            Grid[X][Y] = ArrayBuffer[X][Y];
        }
    }
}

// NOTE(Jesse):

void
tetrimino::MoveLeft(void)
{
    --Pos.X;
}

void
tetrimino::MoveRight(void)
{
    ++Pos.X;
}

void
tetrimino::MoveDown(void)
{
    ++Pos.Y;
}

void
tetrimino::MoveUp(void)
{
    --Pos.Y;
}

tetrimino.h:

/*
  Author: Jesse Coyle
  Description: Tetrimino class header file
  Date: 1/28/2015
*/

#ifndef TETRIMINO_H

struct position
{
    int X;
    int Y;
};

class tetrimino
{
private:
    int Grid[4][4]; //contains only zeros and ones
    char Color;
    position Pos;

public:
    // constructor
    tetrimino(int Type = 7); // valid type values are 0-6

    char GetColor(void);
    position GetPosition(void);
    void GetGrid(int Grid[][4]);

    void CopyArray(int const Array[][4], int ArrayCopy[][4]);
    void PrintArray(int Array[][4]);

    void SetPosition(position NewPos);
    void SetPosition(int X, int Y);

    void RotateClockwise(void);
    void RotateCounterClockwise(void);
    void MoveLeft(void);
    void MoveRight(void);
    void MoveDown(void);
    void MoveUp(void);
};
#define TETRIMINO_H
#endif

well.cpp:

well::well(void)
{
    Width = 8;
    Height = 24;

    FillArray(Grid, '.');

    /*
    int BufferGrid[24][8] =
    {
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {1, 1, 1, 1, 1, 1, 1, 1},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0}
    }

    CopyGrid(BufferGrid, Grid);
    */
}

void
well::CopyArray(char const Array[][8], char ArrayCopy[][8])
{
    for (int Y = 23; Y > 0; --Y)
    {
        for (int X = 0; X < 8; ++X)
        {
            ArrayCopy[Y][X] = Array[Y][X];
        }
    }
}

void const
well::PrintArray(char Array[][8], int Width)
{
    for (int Y = 23; Y >= 0; --Y)
    {
        for (int X = 0; X < 8; ++X)
        {
            cout << setw(Width) << Array[Y][X];
        }
        cout << endl;
    }
}

void
well::FillArray(char Array[][8], char Character)
{
    for (int Y = 23; Y >= 0; --Y)
    {
        for (int X = 0; X < 8; ++X)
        {
            Array[Y][X] = Character;
        }
    }
}

// TODO(Jesse): Fix possible spawning in another tetrimino
// NOTE(Jesse): Could be optimized through caches, though don't bother...
// Although might be a good idea at some point. Depending on how I want to
// Do game update rates
bool
well::DoesPieceFit(tetrimino Object)
{
    // NOTE(Jesse): I'm going to overcomplicate this...
    int ObjectGrid[4][4];
    Object.GetGrid(ObjectGrid);
    int Left;
    int Right;
    int Top;

    position Pos = Object.GetPosition();

    bool FoundBarrier = false;

    for(int X = 0; X < 4; ++X)
    {
        for(int Y = 0; Y < 4; ++Y)
        {
            if(ObjectGrid[Y][X] == 1)
            {
                Left = X;
                FoundBarrier = true;
                break;
            }
        }
        if(FoundBarrier)
        {
            break;
        }
    }

    FoundBarrier = false;

    for(int X = 3; X >= 0; --X)
    {
        for(int Y = 0; Y < 4; ++Y)
        {
            if(ObjectGrid[Y][X] == 1)
            {
                Right = X;
                FoundBarrier = true;
                break;
            }
        }
        if(FoundBarrier)
        {
            break;
        }
    }

    FoundBarrier = false;

    for(int Y = 0; Y < 4; ++Y)
    {
        for(int X = 0; X < 4; ++X)
        {
            if(ObjectGrid[Y][X] == 1)
            {
                Top = X;
                FoundBarrier = true;
                break;
            }
        }
        if(FoundBarrier)
        {
            break;
        }
    }

    if(Pos.X + Left >= 0 &&
        Pos.X + Right <= 7 &&
        Pos.Y - Top >= 0)
    {
        return true;
    }

    return false;
}

void
well::AddPieceToWell(tetrimino Object)
{
    position PiecePos;

    //Integrate into well

    PiecePos = Object.GetPosition();
    int PieceGrid[4][4];
    Object.GetGrid(PieceGrid);

    PrintArray(PieceGrid);

    cout << Object.GetColor();

    cout << "(" << PiecePos.X << ", " << PiecePos.Y << ")" << endl;

    //Y is different to compensate for mysterious Y offset (Note): May be just from displaying?
    for(int YOffset = 0; YOffset < 4; ++YOffset)
    {
        for(int XOffset = 0; XOffset < 4; ++XOffset)
        {
            if(PieceGrid[YOffset][XOffset] == 1)
            {
                Grid[PiecePos.Y + YOffset][PiecePos.X + XOffset] = Object.GetColor();   
            }
        }
    } 
}

bool
well::IsRowFull(int Y)
{
    for(int X = 0;
            X < 8;
            ++X)
    {
        if(Grid[Y][X] == '.')
        {
            return false;
        }
    }

    return true;
}

void
well::ClearRow(int Y)
{
    for(int X = 0; X < 8; ++X)
    {
        Grid[Y][X] = '.';
    }
}

//Call Every Frame?
int
well::ClearFullRows(void)
{
    static int Score = 0;
    bool HadCleared = false;
    for(int Y = 0; Y < 24; ++Y)
    {
        if(IsRowFull(Y))
        {
            ClearRow(Y);
            Score += 100;
            HadCleared = true;
        }
    }

    bool LineCascaded = false;
    for(int Y = 0; Y < 23; ++Y)
    {
        for(int X = 0; X < 8; ++X)
        {
            if(Grid[Y][X] != '.' && Grid[Y+1][X] == '.')
            {
                char Buffer1 = Grid[Y][X];
                char Buffer2 = Grid[Y+1][X];

                Grid[Y+1][X] = Buffer1;
                Grid[Y][X] = '.';
                LineCascaded = true;
            }
            //Trying to fix weird missing dots for empty spots.
            if(Grid[Y][X] == ' ')
            {
                Grid[Y][X] = '.';
            }
        }
        if(LineCascaded)
        {
            Y = 0;
            LineCascaded = false;
        }
    }

    // NOTE(Jesse): This isn't working out...
    /*
    //CascadeRows Down
    if(HadCleared)
    {
        bool ClearTop = true;
        bool ClearBottom = true;
        int MemoryY = 0;

        // NOTE(Jesse): Like Bubblesort But more of a weird cocktail sort kinda method.
        while(!ClearTop && !ClearBottom)
        {
            bool WillBreak = false;
            ClearTop = true;
            ClearBottom = true;
            for(int Y = MemoryY; Y < GetHeight(); ++Y)
            {
                for(int X = 0; X < GetWidth(); ++X)
                {
                    if(Grid[Y][X] != ' ' && Grid[Y+1][X] == ' ')
                    {
                        Grid[Y+1][X] == Grid[Y][X];
                        Grid[Y][X] = ' ';
                        ClearBottom = false;
                        MemoryY = Y;
                        WillBreak = true;
                    }
                }
                if(WillBreak)
                {
                    WillBreak = false;
                    break;
                }
            }
            for(int Y = MemoryY; Y >= 0; --Y)
            {
                for(int X = 0; X < GetWidth(); ++X)
                {
                    if(Grid[Y][X] != ' ' && Grid[Y-1][X] == ' ')
                    {
                        Grid[Y-1][X] = Grid[Y][X];
                        Grid[Y][X] = ' ';
                        ClearTop = false;
                        MemoryY = Y;
                        WillBreak = true;
                    }
                }
                if(WillBreak)
                {
                    WillBreak = false;
                    break;
                }
            }
        }
    }
    */

    return Score;
}

//Best to be tested later
bool
well::TopExeeded(void)
{

    return false;
}

// NOTE(Jesse): May never use this, I may just use copy array. [it just calls copy array anyway]
void
well::GetGrid(char AGrid[][8])
{
    CopyArray(Grid, AGrid);
}

void
well::PrintWell(int Width)
{
    // TODO(Jesse): This is printing out some weird stuff... Possibly a linker error?
    // NOTE(Jesse): Problem was that the conditional didn't like the GetWidth and GetHeight statements.
    for(int Y = 0;
            Y < 24;
            ++Y)
    {
        for(int X = 0;
                X < 8;
                ++X)
        {
            cout << setw(Width) << Grid[Y][X];
        }
        cout << endl;
    }
}

// NOTE(Jesse): Testing Purposes for class methods
void
well::DataDump(int Width)
{
    PrintWell(Width);
}

well.h:

#ifndef WELL_H

#include "tetrimino.h"

class well
{
private:
    char Grid[24][8];
    int Width;
    int Height;

public:
    well(void);

    bool DoesPieceFit(tetrimino Object);
    bool TopExeeded(void);
    bool IsRowFull(int Row);

    int ClearFullRows(void);

    void CascadeRows(void);
    void PrintArray(char Array[][8], int Width);
    void CopyArray(char const Array[][8], char ArrayCopy[][8]);
    void FillArray(char Array[][8], char Character);
    void ClearRow(int Row);
    void GetGrid(char Grid[][8]);
    void AddPieceToWell(tetrimino Object);
    void PrintWell(int Width);
    void DataDump(int Width);
};
#define WELL_H
#endif

由于可能出现的其他错误,我提前道歉,但我想我可以在这个奇怪的链接器错误之后修复它们。

这就是我构建文件的方式。就像手工制作的英雄一样:

@ECHO OFF

DEL build\*.* /q /s

IF NOT EXIST "build" mkdir "build"

set CommonCompilerFlags = -Z7
set CommonLinkerFlags = -incremental:no -opt:ref

REM 32-bit build
REM cl %CommonCompilerFlags% ..\code\src.cpp /link -subsystem:windows,5.1 %CommonLinkerFlags%

REM 64-bit build
CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
REM Optimization switches /O2
CD build
cl %CommonCompilerFlags% ..\code\tetrimino.cpp /link %CommonLinkerFlags%
cl %CommonCompilerFlags% ..\code\well.cpp /link %CommonLinkerFlags%
cl %CommonCompilerFlags% ..\code\src.cpp /link %CommonLinkerFlags%

0 个答案:

没有答案