C++#包括导致';重复符号'; 我启动C++ OpenGL项目,我从两个.CPP文件开始,代码“>场景和样板(不带.h文件!)代码>样板文件包含简单设置环境的OpenGL过程
我想我应该把它们移到这个单独的文件中,以便在C++#包括导致';重复符号'; 我启动C++ OpenGL项目,我从两个.CPP文件开始,代码“>场景和样板(不带.h文件!)代码>样板文件包含简单设置环境的OpenGL过程,c++,cmake,C++,Cmake,我想我应该把它们移到这个单独的文件中,以便在场景中给自己更多的空间,但是现在我已经这样做了,并试图将这个文件包括在场景中,我在链接时遇到了“重复符号”错误,例如 Scanning dependencies of target Coursework [ 33%] Building CXX object CMakeFiles/Coursework.dir/Scene.cpp.o [ 66%] Linking CXX executable Coursework duplicate symbol __Z
场景中给自己更多的空间,但是现在我已经这样做了,并试图将这个文件包括在场景中,我在链接时遇到了“重复符号”错误,例如
Scanning dependencies of target Coursework
[ 33%] Building CXX object CMakeFiles/Coursework.dir/Scene.cpp.o
[ 66%] Linking CXX executable Coursework
duplicate symbol __Z12checkGLErrorv in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
duplicate symbol __Z5setupv in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
duplicate symbol _height in:
CMakeFiles/Coursework.dir/Scene.cpp.o
CMakeFiles/Coursework.dir/boilerplate.cpp.o
...
每个“重复符号”都来自样板文件.cpp
中的定义
为什么我会犯这些错误?我认为#include
ing实际上等同于将该文件的代码复制并粘贴到当前文件中,但是当我实际执行此操作时,它构建得很好
我正在使用CMake进行构建,以防这是相关的(这是一个链接错误,所以可能与此相关?)
这是供参考的文件
Scene.cpp:
#include <iostream>
#include <glut/glut.h>
#include "boilerplate.cpp"
void draw() {
glClearColor(0.2f, 0.2f, 0.2f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// make beautiful models
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
setup();
glutDisplayFunc(draw);
checkGLError();
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
你说得对,把内容复制粘贴到相应的位置
但是,如果包含的文件不仅包含声明和类定义,而且还包含变量定义或函数/方法意义上的实现,那么如果
a、 )您可以在其他几个文件中包含相同的样板文件.cpp
;这将导致重新定义相同的内容->重复符号错误
b、 )您只在一个文件中包含boilerplate.cpp
,但编译器也将boilerplate.cpp
文件视为单独的翻译单元->重复符号
因此,避免包含.cpp文件;而是将该.cpp文件提供的函数作为函数原型(即没有主体的函数)公开在适当的.h文件中;然后只包括.h文件。你说得对。#include
-ing就像在相应位置复制粘贴内容一样
但是,如果包含的文件不仅包含声明和类定义,而且还包含变量定义或函数/方法意义上的实现,那么如果
a、 )您可以在其他几个文件中包含相同的样板文件.cpp
;这将导致重新定义相同的内容->重复符号错误
b、 )您只在一个文件中包含boilerplate.cpp
,但编译器也将boilerplate.cpp
文件视为单独的翻译单元->重复符号
因此,避免包含.cpp文件;而是将该.cpp文件提供的函数作为函数原型(即没有主体的函数)公开在适当的.h文件中;当时只包含.h文件。我的问题是,我想简单地将#include
用作复制和粘贴工具,但我将CMakeboilerplate.cpp
作为一个单独的可执行文件,并试图将其链接和包含在场景中。cpp
导致了这些重复的符号错误
从CMake中删除样板文件.cpp
,即从
set(SOURCE_FILES Scene.cpp boilerplate.cpp)
解决了这个问题并允许我建造它
但正如评论所说,“正确的”方法是给boilerplate.cpp
一个头文件,并包含这个头文件。我不明白为什么这是首选的方式,直到我读到:
我的问题是,我想把#include
简单地用作一个复制和粘贴工具,但我把CMakeboilerplate.cpp
作为一个单独的可执行文件,并试图在场景中链接它和#include
它。cpp
导致了这些重复的符号错误
从CMake中删除样板文件.cpp
,即从
set(SOURCE_FILES Scene.cpp boilerplate.cpp)
解决了这个问题并允许我建造它
但正如评论所说,“正确的”方法是给boilerplate.cpp
一个头文件,并包含这个头文件。我不明白为什么这是首选的方式,直到我读到:
不要#包含一个.cpp文件!您需要创建一个头文件,其中只包含样板文件.cpp
的声明。不要在其他文件中包含.cpp
文件。不过,我认为.h和.cpp文件之间没有真正的区别,将接口与实现分离只是一种“良好做法”?这个问题虽然已经解决,可能会有帮助:当然,文件之间没有区别。一个文件与任何其他文件没有区别。只是文件里的东西很重要。如果包含定义符号的内容,则该符号将由包含的每个文件定义。因此,重复的符号.h
文件仅包含声明,而不包含完整的定义。文件扩展名之间没有区别,重要的是它们的内容。不要包含.cpp文件!您需要创建一个头文件,其中只包含样板文件.cpp
的声明。不要在其他文件中包含.cpp
文件。不过,我认为.h和.cpp文件之间没有真正的区别,将接口与实现分离只是一种“良好做法”?这个问题虽然已经解决,可能会有帮助:当然,文件之间没有区别。一个文件与任何其他文件没有区别。只是文件里的东西很重要。如果包含定义符号的内容,则该符号将由包含的每个文件定义。因此,重复的符号.h
文件仅包含声明,而不包含完整的定义。文件扩展名之间没有区别,重要的是它们的内容。出于某种原因,从源文件列表中删除样板文件.cpp
,CMake可以看到
set(SOURCE_FILES Scene.cpp boilerplate.cpp)