'渲染':'课程'类型重新定义(C2011)

时间:2018-01-20 20:38:53

标签: c++ visual-studio

关于此主题,Stack Overflow上有很多类似的问题。

我正在创建一个包含多个文件(.cpp和.h)的项目。我收到了错误:

  

C2011:' Render':' class'类型重新定义

我已经读过它了。有些人说使用防护,所以我在所有头文件上使用#pragma once。有人说头部被多次包括在内,但是警卫会阻止它。那么我做错了什么?

代码:

Cubes.h

#pragma once

char orientation(int sides, int hV);

std::vector<char> visOrd(std::string *xOrd, int *pov, int ord);

std::vector<int> convertColour(std::vector<std::string> rlBoxCol);

std::tuple<std::vector<int>, std::vector<std::string>> organiseLayers(std::vector<int> boxCoords, std::vector<std::string> rlBoxCol, std::vector<float> rot);


class Render
{
private:
    std::vector<float> rot;
    std::vector<int> boxCoords;
    std::vector<std::string> rlBoxCol;
    int gridSize;
    int cubeSize;
    std::vector<int> offset;

public:
    Render();


    void setRotation(std::vector<float> setRot);
    std::vector<float> getRotation();

    void setCoordinates(std::vector<int> setBoxCoords);
    std::vector<int> getCoordinates();

    void setColours(std::vector<std::string> setRlBoxCol);
    std::vector<std::string> getColours();

    void setSizeOfGrid(int setGridSize);
    int getSizeOfGrid();

    void setSizeOfCubes(int setCubeSize);
    int getSizeOfCubes();

    void setOffset(std::vector<int> setOffset);
    std::vector<int> getOffset();


    void display();
};

Cubes.cpp

#include "Cubes.h"
#include "Global.h"

char orientation(int sides, int hV)
{
// Code
}

std::vector<char> visOrd(std::string *xOrd, int *pov, int ord)
{
// Code
}


std::vector<int> convertColour(std::vector<std::string> rlBoxCol)
{
// Code
}

std::tuple<std::vector<int>, std::vector<std::string>> organiseLayers(std::vector<int> boxCoords, std::vector<std::string> rlBoxCol, std::vector<float> rot)
{
// Code
}



Render::Render()
{
    this->rot;
    this->boxCoords;
    this->rlBoxCol;
    this->gridSize;
    this->cubeSize;
    this->offset;
}


void Render::setRotation(std::vector<float> setRot)
{ // Set rotation
    rot = setRot;
}
std::vector<float> Render::getRotation()
{ // Get rotation
    return rot;
}

void Render::setCoordinates(std::vector<int> setBoxCoords)
{
    boxCoords = setBoxCoords;
}
std::vector<int> Render::getCoordinates()
{
    return boxCoords;
}

void Render::setColours(std::vector<std::string> setRlBoxCol)
{
    rlBoxCol = setRlBoxCol;
}
std::vector<std::string> Render::getColours()
{
    return rlBoxCol;
}

void Render::setSizeOfGrid(int setGridSize)
{
    gridSize = setGridSize;
}
int Render::getSizeOfGrid()
{
    return gridSize;
}

void Render::setSizeOfCubes(int setCubeSize)
{
    cubeSize = setCubeSize;
}
int Render::getSizeOfCubes()
{
    return cubeSize;
}

void Render::setOffset(std::vector<int> setOffset)
{
    offset = setOffset;
}
std::vector<int> Render::getOffset()
{
    return offset;
}


void Render::display()
{
// Drawing code
}

修改

我现在已经按照你说的方式更改了代码。现在我收到错误LNK2005和LNK1169。现在出了什么问题?

编辑2 :(错误)

  

LNK2005

     

&#34; class sf :: RenderWindow Window&#34; (?Window @@ 3VRenderWindow @sf @@ A)已在Cubes.obj中定义

     

C:\ Users \ George \ Documents \ C ++ \ Projects \ Don \ ttat \ t \ n \ t \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \\ n \\ n \\ n \\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

  

LNK2005

     

&#34; class std :: basic_string,class std :: allocator&gt;状态&#34; (?status @@ 3V?$ basic_string @ DU?$ char_traits @ D @ std @@ V?$ allocator @ D @ 2 @@ std @@ A)已在Cubes.obj中定义

     

C:\ Users \ George \ Documents \ C ++ \ Projects \ Don \ ttat \ t \ n \ t \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \\ n \\ n \\ n \\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

  

LNK1169

     

找到一个或多个多重定义的符号

     

C:\ Users \ George \ Documents \ C ++ \ Projects \ Don&tt tt \ Debug \ Don \'t * fall.exe 1

Global.h:

#pragma once
#include <SFML\Graphics.hpp>

// This is where all my global variables will be


extern sf::RenderWindow Window(sf::VideoMode(500, 500), "Maximize window to play the game");
extern std::string status = "NULL";

2 个答案:

答案 0 :(得分:1)

你的Cubes.cpp确实重新定义了Render类。通常,.h文件具有类原型,而.cpp定义方法。

尝试将其添加到Cubes.cpp的顶部:

#include "Cubes.h"

从Cubes.cpp:

的顶部删除它
class Render
{
private:
    std::vector<float> rot;
    std::vector<int> boxCoords;
    std::vector<std::string> rlBoxCol;
    int gridSize;
    int cubeSize;
    std::vector<int> offset;

public:   

并将其从底部删除:

};

答案 1 :(得分:0)

这不是你如何在C ++中提供类的实现。关键字class定义了类,这是您在标题(.h文件)中的内容。在.cpp文件中,您希望实现在头文件中定义的方法,因此不应重新定义整个类。相反,您需要为类的方法(成员函数)提供实现,如下所示:

void Render::setRotation(std::vector<float> setRot)
{ // Set rotation
    rot = setRot;
}

std::vector<float> Render::getRotation()
{ // Get rotation
    return rot;
}

注意前缀Render::?这就是您如何表明您正在为类setRotation的函数Render提供实现。只需在cpp中添加这样的函数实现,不要将它们嵌套在class中,不要包含任何字段(成员字段已在标题中定义,它们已完成)。

<强>更新

好的,所以根据更新的答案,您的链接器错误引用了实例sf::RenderWindow Windowstd::string status;将main.obj(来自main.cpp?)与Cubes.obj相关联时会发生此错误。该错误告诉您main.objCubes.obj都定义了这些变量。

我建议您阅读&#34;编译单元&#34;在C ++中,符号的声明定义之间的区别;但要提供非常简要摘要:

本质上,编译器运行在单个&#34;编译单元&#34 ;;你可以把它想象成一个单独的文件。 #include - 语句的作用基本上是将包含文件的内容复制/粘贴到编译单元中。因此,当您编译Cubes.cpp时,它将遍历所有嵌套包含,直到它生成一个包含所有内容的巨大cpp文件。然后它会将其构建为.obj文件。然后,您使用main.cpp和您可能拥有的任何其他.cpp文件执行相同的操作。最后,链接器将尝试将这些目标文件链接在一起以生成最终结果。

现在,如果链接器在链接两个对象时发现重复的定义,则会出现错误。所以你不能有两个同名的全局变量!如果Cubes.cppmain.cpp都包含global.h,则两个编译单元都包含全局变量定义Windowstatus。这导致链接器错误。

这就是你在标题中放入声明的原因(因为它包含在多个编译单元中),以及源文件中的定义(通常不包括在其他地方) )。您构建源文件以生成包含定义的唯一对象文件;所有其他目标文件仅引用声明。然后,链接器可以将这些引用链接到目标文件中的定义

因此,您希望声明标头中的变量,并将定义移动到其他位置。例如,main.cpp;但这完全取决于您的应用程序的其余部分以及您要实现的目标。超出了问题的范围。