C++错误:类函数的多个定义

Sch*_*mer 2 c++ linker compiler-errors makefile

我在.h文件中有一个C++ classe,如下所示:

#ifndef __GLWidget_h__
#define __GLWidget_h__

class PivotShape
{
    // This is allowed
    void do_something() { std::cout << "Doing something\n"; }

    // This is not allowed
    void do_something_else();
}

// This is not allowed
void PivotShape::do_something_else()
{
    std::cout << "Doing something else\n";
}

#endif
Run Code Online (Sandbox Code Playgroud)

如果我在类声明中添加方法,一切似乎都很好.但是如果我在类声明之外添加方法,我会得到如下错误:

/usr/share/qt4/bin/moc GLWidget.h > GLWidget_moc.cpp
/programs/gcc-4.6.3/installation/bin/g++ -W -Wall -g -c -I./ -I/usr/include/qt4 GLWidget_moc.cpp
/programs/gcc-4.6.3/installation/bin/g++ main.o GLState.o GLWidget.o MainWindow_moc.o GLWidget_moc.o -L/usr/lib/x86_64-linux-gnu -lQtGui -lQtOpenGL -lQtCore -lGLU -lGL -lm -ldl -o main
GLWidget.o: In function `std::iterator_traits<float const*>::iterator_category std::__iterator_category<float const*>(float const* const&)':
/home/<user>/<dir>/<dir>/<dir>/<dir>/<dir>/GLWidget.h:141: multiple definition of `PivotShape::do_someting_else()'
main.o:/home/<user>/<dir>/<dir>/<dir>/<dir>/<dir>/GLWidget.h:141: first defined here
Run Code Online (Sandbox Code Playgroud)

我认为复制是由Make文件中的这个片段引起的.我认为.h文件正在转换为_moc.cpp文件,这允许多个包含:

# Define linker
LINKER        = /programs/gcc-4.6.3/installation/bin/g++

MOCSRCS       = $(QTHEADERS:.h=_moc.cpp)

# Define all object files to be the same as CPPSRCS but with all the .cpp
# suffixes replaced with .o
OBJ           = $(CPPSRCS:.cpp=.o) $(MOCSRCS:.cpp=.o)
Run Code Online (Sandbox Code Playgroud)

这是问题吗?如果是这样,我该如何解决?如果没有,发生了什么?

我认为在C++中将类方法包含在类声明的主体中是违法的.如果这是合法的,那么它似乎是解决问题的简单方法.这合法吗?

编辑:

我忘了提到我已经发现声明方法inline有效,但我想知道如何避免重复.

Mik*_*our 10

你打破了一个定义规则; 在标题中定义函数意味着每个翻译单元中都有一个包含标题的定义,并且通常只允许在程序中使用单个定义.

选项:

  • 将函数定义移动到源文件中,因此只有一个定义; 要么
  • 添加inline到函数定义,放宽规则并允许多个定义; 要么
  • 定义类中的函数,使其隐式内联.(回答你的最后一个问题,是的,这是合法的.)

另外,不要使用保留名称一样__GLWidget_h__.

  • @Schemer:是的,你在每个翻译单元中得到一个定义(翻译单元对应一个源文件及其包含的所有内容).包含防护措施可以防止每个单元中的多个定义,但不会在其他单元中停止定义.只要定义相同,就可以在多个单元中定义类定义,内联函数,模板和各种其他内容.非内联函数和变量只能定义一次. (2认同)