I have a C++ classe in a .h file like this:
#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
If I add methods inside the class declaration everything seems fine. But if I add methods outside of the class declaration, I get errors like this:
/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
I think the duplication is being caused by this snippet in the Make file. I think the .h files are being converted to _moc.cpp files and this is allowing the multiple inclusions:
# 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)
Is this the problem? If so, how can I fix it? If not, what's going on?
I thought it was illegal in C++ to include class methods inside the body of the class declaration. If this is legal, then it seems like an easy way to solve the problem. Is this legal?
Edit:
I forgot to mention that I had already discovered that declaring the methods as inline
works, but I was wondering how to avoid the duplication.
You're breaking the One Definition Rule; defining the function in the header means there's a definition in every translation unit that includes the header, and you're usually only allowed a single definition in the program.
Options:
inline
to the function definition, to relax the rule and allow multiple definitions; orAlso, don't use reserved names like __GLWidget_h__
.
Define the function in a source file or use inline
to define it in the header file, outside the class definition.
Note that you can still define it inside the class definition without the inline
keyword.
Related: Member function definition
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With