Multiple definition error in C++, using header files - c++

im new to programming in C++, but have some experience with Java. Ive created a very basic class called Dog.cpp and its header file Dog.hpp. Netbeans will not build the project, giving me an error stating multiple definitions of both the constructor and the getAge function. As far as I am concerned I have declared the constructor and function in the header file, and defined them in the class file. Where have i gone wrong?
Thanks in advance!
Dog.hpp:
#include <iostream>
using namespace std;
class Dog
{
public:
Dog(int someAge); // Constructor
~Dog(); // Destructor
int getAge() const; // function prototype
private:
int itsAge; // age variable
};
Dog.cpp:
#include "Dog.hpp"
using namespace std;
Dog::Dog(int anAge)
{
cout << "Dog created \n";
}
int Dog::getAge() const
{
return itsAge;
}
** main.cpp
#include <iostream>
#include "Dog.cpp"
int main()
{
Dog aDog(5);
cout << aDog.getAge();
return 0;
}
Netbeans output:
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/sams_-_hour_10
make[2]: Entering directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
g++ -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/Dog.o.d
g++ -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/Dog.o.d -o build/Debug/GNU-Linux-x86/Dog.o Dog.cpp
mkdir -p dist/Debug/GNU-Linux-x86
g++ -o dist/Debug/GNU-Linux-x86/sams_-_hour_10 build/Debug/GNU-Linux-x86/main.o build/Debug/GNU-Linux-x86/Dog.o
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::Dog(int)':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: multiple definition of `Dog::Dog(int)'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: first defined here
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::Dog(int)':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: multiple definition of `Dog::Dog(int)'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:12: first defined here
build/Debug/GNU-Linux-x86/Dog.o: In function `Dog::getAge() const':
/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:18: multiple definition of `Dog::getAge() const'
build/Debug/GNU-Linux-x86/main.o:/home/david/NetBeansProjects/C++/SAMS - Hour 10/Dog.cpp:18: first defined here
build/Debug/GNU-Linux-x86/main.o: In function `main':
main.cpp:(.text+0x6d): undefined reference to `Dog::~Dog()'
main.cpp:(.text+0x7f): undefined reference to `Dog::~Dog()'
collect2: error: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/sams_-_hour_10] Error 1
make[2]: Leaving directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/david/NetBeansProjects/C++/SAMS - Hour 10'
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 931ms)

It seems that you included the cpp module (Dog.cpp) with the member function definitions in the module with function main. You should include only headers.
Change Main.cpp the following way
#include <iostream>
#include "Dog.hpp"
int main()
{
Dog aDog(5);
cout << aDog.getAge();
return 0;
}
Take into account that you forgot to set data member itsAge in the construtor. It should look as
Dog::Dog(int anAge) : itsAge( anAge )
{
cout << "Dog created \n";
}
And you forgot also to define the destructor.
You could write in the class definition for example the following way
class Dog
{
public:
Dog(int someAge); // Constructor
~Dog() = default; // Destructor
int getAge() const; // function prototype
private:
int itsAge; // age variable
};
provided that the compiler supports this specifier.

Try doing either this in your 'Dog.hpp':
#ifndef HEADER_GUARD // Top of file
#define HEADER_GUARD
/* Code in your class here. */
#endif // End of file
Or this at top of the file:
#pragma once
The former block of code will tell the preprocessor to only include the code within the guard as long as the header guard definition ("FILENAME_HPP" for instance) is not defined. It immediately gets defined if that conditional passes, so the code should only be loaded once.
The latter block will also work - and possibly be more effective - on most compilers, including g++ and Visual C++. It tells the compiler to process the file only once.
Also, you seem to be missing a definition for your class's destructor.
Another Edit: One more thing, it is very bad programming practice to #include .cpp files. Always #include the header files that are associated with them.

Related

Simple C++ code with templates won't compile due to undefined references [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
"undefined reference" to a template class function
(4 answers)
Closed 4 months ago.
I have searched high and low for answers on this but I'm still baffled. As far as I understand from the examples I've found online my code should be valid but it won't compile due to undefined references. I figured out how to get it to compile but I think that's not how one is supposed to do it. So the following is a question I'd very much appreciate answers to.
I'd like to implement a class in C++ with a template member similarly to how std::vector for example can contain data of any type. The following is a minimal example that reproduces the issue.
main.cpp:
#include <iostream>
#include <cstdlib>
#include "Foo.h"
int main(int argc, char** argv) {
Foo<int> foo_int;
Foo<float> foo_flt;
return 0;
}
Foo.h:
#ifndef FOO_H
#define FOO_H
template<class T> class Foo {
public:
Foo();
Foo(const Foo& orig) = delete;
virtual ~Foo();
private:
T* m_f;
};
#endif /* FOO_H */
Foo.cpp
#include <iostream>
#include <typeinfo>
#include "Foo.h"
template<class T> Foo<T>::Foo() {
std::cout << "Constructing a Foo<" << typeid(T).name() << ">!" << std::endl;
m_f = new T;
}
template<class T> Foo<T>::~Foo() {
std::cout << "Destructing a Foo<" << typeid(T).name() << ">!" << std::endl;
}
Now if I try to build the code in NetBeans IDE I get the following output.
cd '/home/pete/Dropbox/NetBeans/Foodinger'
/usr/bin/make -f Makefile CONF=Debug
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory '/home/pete/Dropbox/NetBeans/Foodinger'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux/foodinger
make[2]: Entering directory '/home/pete/Dropbox/NetBeans/Foodinger'
mkdir -p build/Debug/GNU-Linux
rm -f "build/Debug/GNU-Linux/Foo.o.d"
g++ -c -g -std=c++14 -MMD -MP -MF "build/Debug/GNU-Linux/Foo.o.d" -o build/Debug/GNU-Linux/Foo.o Foo.cpp
mkdir -p build/Debug/GNU-Linux
rm -f "build/Debug/GNU-Linux/main.o.d"
g++ -c -g -std=c++14 -MMD -MP -MF "build/Debug/GNU-Linux/main.o.d" -o build/Debug/GNU-Linux/main.o main.cpp
mkdir -p dist/Debug/GNU-Linux
g++ -o dist/Debug/GNU-Linux/foodinger build/Debug/GNU-Linux/Foo.o build/Debug/GNU-Linux/main.o
build/Debug/GNU-Linux/main.o: In function `main':
/home/pete/Dropbox/NetBeans/Foodinger/main.cpp:8: undefined reference to `Foo<int>::Foo()'
/home/pete/Dropbox/NetBeans/Foodinger/main.cpp:9: undefined reference to `Foo<float>::Foo()'
/home/pete/Dropbox/NetBeans/Foodinger/main.cpp:9: undefined reference to `Foo<float>::~Foo()'
/home/pete/Dropbox/NetBeans/Foodinger/main.cpp:8: undefined reference to `Foo<int>::~Foo()'
/home/pete/Dropbox/NetBeans/Foodinger/main.cpp:8: undefined reference to `Foo<int>::~Foo()'
collect2: error: ld returned 1 exit status
nbproject/Makefile-Debug.mk:63: recipe for target 'dist/Debug/GNU-Linux/foodinger' failed
make[2]: *** [dist/Debug/GNU-Linux/foodinger] Error 1
make[2]: Leaving directory '/home/pete/Dropbox/NetBeans/Foodinger'
nbproject/Makefile-Debug.mk:60: recipe for target '.build-conf' failed
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory '/home/pete/Dropbox/NetBeans/Foodinger'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 760ms)
My understanding is that one should only #include header files and the .cpp files should be given as arguments to the compiler. That's what the build seems to be doing according to its output. If I however add #include "Foo.cpp" to main.cpp the program seems to compile and run just fine. But isn't this how one is not supposed to do it? Or have I found some special case here where I have to #include the .cpp file? Is NetBeans doing something wrong? Is there something wrong with my implementation using templates? At least the code compiles fine if I get rid of them.
Thanks.

Having issue linking with an external array declared in a header file and defined in a source file

I need to declare a very large n-d array. It is defined in a header file and never changes. Unfortunately compiling the main file takes a very long time, so I decided to bring it out into it's own object file.
Here is the header file tables.hpp:
#pragma once
namespace TABLES
{
extern const int A[10][10][10];
extern const int B[10][10][10];
}
Here is the source file tables.cpp:
namespace TABLES
{
const int A[10][10][10] = {}; // use default for brevity
const int B[10][10][10] = {}; // use default for brevity
}
and my main file:
#include "tables.hpp"
int main()
{
printf("%d", TABLES::A[0][0][0]);
}
and here is my Makefile:
CXX = clang++
CFLAGS = -std=c++17 -g -flto -Wall -Iinclude/
SRC = src/
INC = include/
tables.o: $(SRC)tables.cpp $(INC)tables.hpp
$(CXX) $(CFLAGS) -c $(SRC)tables.cpp
main: main.cpp tables.o
$(CXX) $(CFLAGS) -o main main.cpp tables.o
the tables.o compiles successfully, however I am having issues linking the tables.o to the main program:
undefined reference to `TABLES::A'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Makefile:30: recipe for target 'main' failed
make: *** [refactor] Error 1

socket.h fails to compile because of <winsock2.h> inclusion

i am using Netbeans 8.1 IDE with g++ compiler (cygwin) to
build a custome Socket class whose implementation is well defined
in socket.cpp, and declared in socket.h as shown below:
//socket.h
#ifndef SOCKET_H
#define SOCKET_H
#include <windows.h>
#include <winsock2.h> /*Code builds successfully if this line is commented. errors otherwise*/
class Socket {
public:
Socket(){std::cout << "Testing: Inside socket constructor ..." << endl;}
Socket(const Socket&);
virtual ~Socket();
Socket& operator=(Socket&);
void Close();
protected:
Socket(SOCKET s); /*Windows socket handle, defined in <winsock2.h>*/
SOCKET s_;
int* refCounter_;
private:
static bool Start();
static void End();
static int nofSockets_;
};
#endif /* SOCKET_H */
now, i test-drove it like this:
//main.cpp
#include "socket.h"
int main() {
Socket socket;
return 0;
}
Above code built successfully when winsock2.h is removed, error otherwise.
Honestly i am new to the netbeans IDE and i can't understand what am doing
wrong. I Dont know what the IDE requires of me either. i need your help to
debugg this please. Thanks. Here's the error:
cd 'C:\wamp\www\klandestine'
C:\cygwin64\bin\make.exe -f Makefile CONF=Debug clean
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .clean-conf
make[1]: Entering directory '/cygdrive/c/wamp/www/klandestine'
rm -f -r build/Debug
rm -f dist/Debug/Cygwin-Windows/klandestine.exe
make[1]: Leaving directory '/cygdrive/c/wamp/www/klandestine'
CLEAN SUCCESSFUL (total time: 656ms)
cd 'C:\wamp\www\klandestine'
C:\cygwin64\bin\make.exe -f Makefile CONF=Debug
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory '/cygdrive/c/wamp/www/klandestine'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin-Windows/klandestine.exe
make[2]: Entering directory '/cygdrive/c/wamp/www/klandestine'
mkdir -p build/Debug/Cygwin-Windows
rm -f "build/Debug/Cygwin-Windows/main.o.d"
g++ -c -g -MMD -MP -MF "build/Debug/Cygwin-Windows/main.o.d" -o build/Debug/Cygwin-Windows/main.o main.cpp
In file included from /usr/include/w32api/winsock2.h:56:0,
from socket.h:12,
from main.cpp:14:
/usr/include/w32api/psdk_inc/_fd_types.h:100:2: warning: #warning "fd_set and associated macros have been defined in sys/types. This can cause runtime problems with W32 sockets" [-Wcpp]
#warning "fd_set and associated macros have been defined in sys/types. \
^
In file included from socket.h:12:0,
from main.cpp:14:
/usr/include/w32api/winsock2.h:995:123: error: conflicting declaration of C function 'int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, PTIMEVAL)'
WINSOCK_API_LINKAGE int WSAAPI select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,const PTIMEVAL timeout);
^
In file included from /usr/include/sys/types.h:68:0,
from /usr/include/pthread.h:14,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/x86_64-pc-cygwin/bits/gthr-default.h:35,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/x86_64-pc-cygwin/bits/gthr.h:148,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/ext/atomicity.h:35,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/bits/ios_base.h:39,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/ios:42,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/ostream:38,
from /usr/lib/gcc/x86_64-pc-cygwin/5.3.0/include/c++/iostream:39,
from main.cpp:9:
/usr/include/sys/select.h:73:5: note: previous declaration 'int select(int, _types_fd_set*, _types_fd_set*, _types_fd_set*, timeval*)'
int select __P ((int __n, fd_set *__readfds, fd_set *__writefds,
^
make[2]: *** [nbproject/Makefile-Debug.mk:69: build/Debug/Cygwin-Windows/main.o] Error 1
make[2]: Leaving directory '/cygdrive/c/wamp/www/klandestine'
make[1]: *** [nbproject/Makefile-Debug.mk:60: .build-conf] Error 2
make[1]: Leaving directory '/cygdrive/c/wamp/www/klandestine'
make: *** [nbproject/Makefile-impl.mk:40: .build-impl] Error 2
BUILD FAILED (exit value 2, total time: 3s)

Codelite MinGW G++ Linker Error

I'm having a linker issue with mingw on codelite. When I put the .hpp and .cpp files in main where I'm unit testing, everything works fine.
Here's my .hpp file:
class ITPropertiesBase
{
public:
virtual ~ITPropertiesBase(){}
virtual const char *getName() = 0;
};
template <typename T>
class Properties : public ITPropertiesBase
{
public:
Properties(const char *name, T value);
~Properties();
const char *getName();
private:
const char *m_name;
T m_value;
};
Here's my .cpp file:
template <typename T> Properties<T>::Properties(const char *name, T value) : m_name(name), m_value(value)
{
}
template <typename T> Properties<T>::~Properties()
{
}
template <typename T> const char* Properties<T>::getName()
{
return m_name;
}
And here's my main:
#include <iostream>
#include <vector>
#include <string>
#include "Properties.hpp"
int main(int argc, char **argv)
{
const char *testInput = "test";
std::vector<ITPropertiesBase*> as;
as.push_back(new Properties<int>(testInput, 5));
return 0;
}
And here's the linker output:
C:\Windows\system32\cmd.exe /c "C:/MinGW-4.8.1/bin/mingw32-make.exe -j4 -e -f Makefile"
"----------Building project:[ Interfaces - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'E:/CodeLite/ElysiumEngine/Interfaces'
C:\MinGW-4.8.1\bin\g++.exe -c "E:/CodeLite/ElysiumEngine/Interfaces/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I.
C:\MinGW-4.8.1\bin\g++.exe -c "E:/CodeLite/ElysiumEngine/Interfaces/Properties.cpp" -g -O0 -Wall -o ./Debug/Properties.cpp.o -I. -I.
C:\MinGW-4.8.1\bin\g++.exe -o ./Debug/Interfaces #"Interfaces.txt" -L.
./Debug/main.cpp.o: In function `main':
E:/CodeLite/ElysiumEngine/Interfaces/main.cpp:11: undefined reference to `Properties<int>::Properties(char const*, int)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[1]: *** [Debug/Interfaces] Error 1
mingw32-make.exe: *** [All] Error 2
Interfaces.mk:79: recipe for target 'Debug/Interfaces' failed
mingw32-make.exe[1]: Leaving directory 'E:/CodeLite/ElysiumEngine/Interfaces'
Makefile:4: recipe for target 'All' failed
2 errors, 0 warnings
Anyone know what's going on?
This might apply to you:
Move header files out of source directory.
It works when they are all in the same folder or not, it is best to relocate them. You need to tell the compiler where they are at, in relation to your project.
change to #include <Properties.hpp>
Then place header files into a include directory.
Then in compiler flags, add include directory for header files. typically a directory called include. For example:
-I../include/
This compiler flag will include the parent directory's include folder. All header files in it will become visible to the compiler. Typically all source code or cpp files, are bundled together. Meaning all in the same parent folder for each codelite project.
One other thing, try moving your templates into header files.
Reference http://codelite.org/LiteEditor/ProjectSettings.
edit:added bullets

C++ Function Template Error

I have just started to use the function templates in c++. I am using these tutorials. I am trying to implement a basic code which goes something like this.
#include<iostream>
using namespace std;
template<class t>
t max(t a,t b){
t max_value;
max_value = (a>b)?a:b;
return max_value;
}
int main(){
int a=9,b=8,c;
c=max<int>(a,b);
cout<<c;
return 0;
}
However I get the following error.
/usr/bin/gmake" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
gmake[1]: Entering directory `/home/gursheel/NetBeansProjects/project_q7'
"/usr/bin/gmake" -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/project_q7
gmake[2]: Entering directory `/home/gursheel/NetBeansProjects/project_q7'
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
g++ -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
main.cpp: In function ‘int main()’:
main.cpp:16:19: error: call of overloaded ‘max(int&, int&)’ is ambiguous
main.cpp:16:19: note: candidates are:
main.cpp:4:3: note: t max(t, t) [with t = int]
In file included from /usr/include/c++/4.7/bits/char_traits.h:41:0,
from /usr/include/c++/4.7/ios:41,
from /usr/include/c++/4.7/ostream:40,
from /usr/include/c++/4.7/iostream:40,
from main.cpp:1:
/usr/include/c++/4.7/bits/stl_algobase.h:210:5: note: const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
gmake[2]: *** [build/Debug/GNU-Linux-x86/main.o] Error 1
gmake[2]: Leaving directory `/home/gursheel/NetBeansProjects/project_q7'
gmake[1]: *** [.build-conf] Error 2
gmake[1]: Leaving directory `/home/gursheel/NetBeansProjects/project_q7'
gmake: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 318ms)
I am not able to understand what the error exactly is. Any help would be appreciated.
You need to remove:
using namespace std;
you are clashing with std::max. This is one of the reasons Why “using namespace std;” is considered bad practice and this is the C++ FAQs take on it. Typing std::cout is really not that bad and you will get used to adding std:: pretty quickly and it will just save you trouble in the long run.
The issue here is that the "max" template function that you have defined is conflicting with max function that is part of STL. Both your and STL's have same signature and both are template functions. STL's max is inside namespace "std". But since you have specified "using namespace std" in your code STL's max has become visible. There are 3 ways i can think of to avoid this situation
1) Rename your max as max1 or some other name
2) Comment "using namespace std" and replace cout with std::cout
3) Replace following
c=max<int>(a,b);
with
c=::max<int>(a,b);
Prepending :: to a function call tells the compiler to pick the function from global namespace. Your function is defined in global namespace.
Another way is to add :: when you call your max function template:
c=::max<int>(a,b);
This will tell the compiler to find the max function template in the global namespace. In this case, your version of max will be used. You may find a live demo here: Demo