I am trying to relearn C++ after taking an intro course a few years ago and I’m having some basic problems. My current problem occurs when trying to use a friend function. Here is my code in 2 files.
First:
// fun.cpp #include <iostream> using namespace std; class classA { friend void funct(); public: classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";} private: int propa; int propb; void outfun(){ cout<<"propa="<<propa<<endl<<"propb="<<propb<<endl; } }; void funct(){ // ERROR HERE cout<<"enter funct"<<endl; classA tmp(1,2); tmp.outfun(); cout<<"exit funct"<<endl; }
Second:
// mainfile.cpp #include <iostream> #include "fun.cpp" using namespace std; int main(int nargin,char* varargin[]) { cout<<"call funct"<<endl; funct(); cout<<"exit main"<<endl; return 0; }
The error I am getting is "multiple definition of `funct()'". Am I using the wrong syntax when declaring it as a friend function?
Error Fix. The main function is the entry point for the C++ program execution. The fix for the error is to scan the source files listed in the build log and remove the unwanted main routines in the respective files. We can have one definition of the main function for the project to run.
If you put a definition of a global variable in a header file, then this definition will go to every . c file that includes this header, and you will get multiple definition error because a varible may be declared multiple times but can be defined only once.
Answer: The multiple definitions with the same function name is called Function Overloading. The only difference among those functions is their parameter list which helps the compiler to recognize which function is being executed.
Put int A::val=0; in a cpp file. If you use C++17 another option is to make it an inline variable. Then you don't need to define it anywhere outside the class definition.
Here is a highly simplified but hopefully relevant view of what happens when you build your code in C++.
C++ splits the load of generating machine executable code in following different phases -
Preprocessing - This is where any macros - #define
s etc you might be using get expanded.
Compiling - Each cpp file along with all the #include
d files in that file directly or indirectly (together called a compilation unit) is converted into machine readable object code.
This is where C++ also checks that all functions defined (i.e. containing a body in {
}
e.g. void Foo( int x){ return Boo(x); })
are referring to other functions in a valid manner.
The way it does that is by insisting that you provide at least a declaration of these other functions (e.g. void Boo(int);
) before you call it so it can check that you are calling it properly among other things. This can be done either directly in the cpp file where it is called or usually in an included header file.
Note that only the machine code that corresponds to functions defined in this cpp and included files gets built as the object (binary) version of this compilation unit (e.g. Foo) and not the ones that are merely declared (e.g. Boo).
Linking - This is the stage where C++ goes hunting for stuff declared and called in each compilation unit and links it to the places where it is getting called. Now if there was no definition found of this function the linker gives up and errors out. Similarly if it finds multiple definitions of the same function signature (essentially the name and parameter types it takes) it also errors out as it considers it ambiguous and doesn't want to pick one arbitrarily.
The latter is what is happening in your case. By doing a #include
of the fun.cpp
file, both fun.cpp
and mainfile.cpp
have a definition of funct()
and the linker doesn't know which one to use in your program and is complaining about it.
The fix as Vaughn mentioned above is to not include the cpp file with the definition of funct()
in mainfile.cpp
and instead move the declaration of funct()
in a separate header file and include that in mainline.cpp
. This way the compiler will get the declaration of funct()
to work with and the linker would get just one definition of funct()
from fun.cpp
and will use it with confidence.
The problem is that if you include fun.cpp in two places in your program, you will end up defining it twice, which isn't valid.
You don't want to include cpp
files. You want to include header files.
The header file should just have the class definition. The corresponding cpp
file, which you will compile separately, will have the function definition.
fun.hpp:
#include <iostream> class classA { friend void funct(); public: classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";} private: int propa; int propb; void outfun(){ std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl; } };
fun.cpp:
#include "fun.hpp" using namespace std; void funct(){ cout<<"enter funct"<<endl; classA tmp(1,2); tmp.outfun(); cout<<"exit funct"<<endl; }
mainfile.cpp:
#include <iostream> #include "fun.hpp" using namespace std; int main(int nargin,char* varargin[]) { cout<<"call funct"<<endl; funct(); cout<<"exit main"<<endl; return 0; }
Note that it is generally recommended to avoid using namespace std
in header files.
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