【问题标题】:C++ Error: Multiple definitions of class functions [duplicate]C ++错误:类函数的多个定义[重复]
【发布时间】:2015-04-10 10:20:28
【问题描述】:

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

#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

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

/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

我认为重复是由 Make 文件中的这个 sn-p 引起的。我认为 .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)

这是问题吗?如果是这样,我该如何解决?如果不是,那是怎么回事?

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

编辑:

我忘了提到我已经发现将方法声明为inline 是可行的,但我想知道如何避免重复。

【问题讨论】:

  • inline 现在可能会派上用场。

标签: c++ compiler-errors makefile linker


【解决方案1】:

您违反了单一定义规则;在标头中定义函数意味着在包含标头的每个翻译单元中都有一个定义,并且通常只允许在程序中进行一个定义。

选项:

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

另外,不要像__GLWidget_h__ 一样使用reserved names

【讨论】:

  • 谢谢。那么发生了什么是 A.cpp 和 B.cpp 都包含 .h 文件,导致多个定义?由于#ifndef...#endif 语句,没有单个 .cpp 文件可以包含多个内容。但这不是意味着 .h 文件中的所有类定义都会重复吗?它们是否隐含inline——这就是为什么类中的函数隐含inline
  • @Schemer:是的,您在每个翻译单元中都有一个定义(其中翻译单元对应于源文件及其包含的所有内容)。包含守卫防止每个单元中的多个定义,但不会停止其他单元中的定义。只要定义相同,类定义、内联函数、模板和其他各种东西都可以在多个单元中定义。非内联函数和变量只能定义一次。
  • 扩展 Mike 所说的内容:规则是“每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的一个定义;无需诊断”不需要诊断”意味着其他任何事情都是未定义的行为,即使在实践中,我所知道的所有编译器都会发出多个定义(和缺少定义)的错误信号。
  • 所以,似乎有一些不可避免的代码重复。当我试图诊断问题时,我认为这一定不是,所以我排除了它。感谢所有提供帮助的 cmets!
  • 我想知道为什么当你以这种方式声明/实现模板方法时,这样的代码会起作用?
【解决方案2】:

在源文件中定义函数或使用inline在头文件中定义它,在类定义之外。

请注意,您仍然可以在没有inline 关键字的类定义中定义它。

相关:Member function definition

【讨论】:

    猜你喜欢
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2013-07-28
    相关资源
    最近更新 更多