C++ Error: Multiple definitions of class functions
C++ Error: Multiple definitions of class functions
我在 .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
如果我在 class 声明中添加方法,一切似乎都很好。但是如果我在 class 声明之外添加方法,我会得到这样的错误:
/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 文件中的这段代码引起的。我认为 .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++ 中将 class 方法包含在 class 声明的主体中是非法的。如果这是合法的,那么这似乎是解决问题的一种简单方法。这合法吗?
编辑:
我忘了说我已经发现将方法声明为 inline
是可行的,但我想知道如何避免重复。
在源文件中定义函数或使用 inline
在头文件中定义它,在 class 定义之外。
请注意,您仍然可以在不使用 inline
关键字的 class 定义中定义它。
相关:Member function definition
您违反了单一定义规则;在 header 中定义函数意味着在每个包含 header 的翻译单元中都有一个定义,并且您通常只允许在程序中定义一个定义。
选项:
- 将函数定义移动到一个源文件中,所以只有一个定义;或者
- 在函数定义中添加
inline
,放宽规则,允许多个定义;或者
- 在 class 中定义函数,使其隐式内联。 (回答你的最后一个问题,是的,这是合法的。)
另外,不要像 __GLWidget_h__
那样使用 reserved names。
我在 .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
如果我在 class 声明中添加方法,一切似乎都很好。但是如果我在 class 声明之外添加方法,我会得到这样的错误:
/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 文件中的这段代码引起的。我认为 .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++ 中将 class 方法包含在 class 声明的主体中是非法的。如果这是合法的,那么这似乎是解决问题的一种简单方法。这合法吗?
编辑:
我忘了说我已经发现将方法声明为 inline
是可行的,但我想知道如何避免重复。
在源文件中定义函数或使用 inline
在头文件中定义它,在 class 定义之外。
请注意,您仍然可以在不使用 inline
关键字的 class 定义中定义它。
相关:Member function definition
您违反了单一定义规则;在 header 中定义函数意味着在每个包含 header 的翻译单元中都有一个定义,并且您通常只允许在程序中定义一个定义。
选项:
- 将函数定义移动到一个源文件中,所以只有一个定义;或者
- 在函数定义中添加
inline
,放宽规则,允许多个定义;或者 - 在 class 中定义函数,使其隐式内联。 (回答你的最后一个问题,是的,这是合法的。)
另外,不要像 __GLWidget_h__
那样使用 reserved names。