Should I put these functions in a standalone .h file? - c++

I have a project which includes 2 files: main.cc and header1.h. While main.cc instantiates a class "className" and calls the member functions of it, the header file includes definition of the class.
main.cc:
#include <header1.h>
int main(){
className classobject();
classobject.function1();
...
}
}
header1.h:
class className{
public:
className();
void function1();
...
};
double className::function1(){
double function2(){
...
}
}
With this, I met an error which says:"a function definition should not be placed before '{' token.
So I decided to put the definition of function2 outside of the class, and put it in a standalone .h file. In that way, my project would include 3 files, namely: main.cc, head1.h and function2.h file:
main.cc:
#include <head1.h>
int main(){
className classobject;
void classobject.function1();
...
}
head1.h:
#include <function2.h>
class className{
double function2();
...
}
function2.h:
double function2(){
...
}
Although function2 can also be defined as the class member function so that it can be moved out of function1 while inside the class, I want to know whether the above mentioned treatment is leagal. Besides, does the creation of header files have some implicit rules established by usage (common treatment)?
Could anyone give some comments? Thanks in advance.

The first problem in your code that I see is that you define className::function1 in a header, but forgot to declare it inline. The outcome is that you can only use the header in a single compilation unit †. That's a bad design. I recommend defining it in a source file instead.
Secondly, you try to define function2 inside another function. That's not allowed and therefore you got a compilation error. You say that you decided to move it's definition outside the class, but it's definition was already outside the class definition. Moving the definition outside the definition of className::function1 is indeed a correct choice.
If function2 is reusable outside it's use in className::function1, then it's indeed a good idea and perfectly legal to declare it in a separate header. But just like className::function1, you're defining function2 also in the header again and again without declaring it inline and therefore you will get in trouble if you try to use it in multiple compilation units. I recommend defining function2 in a source file as well.
† If you include the header in multiple compilation units, then each of those compilation units will contain the definition of the function. The One Definition Rule does not allow defining a function in more than one compilation unit. Functions that are marked inline are treated differently. They may be defined in multiple compilation units as long as they have an identical definition in each.

Do something like this in your className.hpp
class className{
public:
className();
private:
void function1();
};
Then in your className.cpp
#include"className.hpp"
className::className(){ /*defintion*/ }
void className::function1(){ /*definition*/ }
Then you could use a makefile in oder to compute the className.o file and link it to the main file.
If you want to define another function (like function2()), you can then define it the className.cpp

Related

g++ cannot link my class function if I define it in a separate file [duplicate]

I'm getting a compiler error when I try to inline a method of one of my classes. It works when I take away the "inline" keyword.
Here's a simplified example:
main.cpp:
#include "my_class.h"
int main() {
MyClass c;
c.TestMethod();
return 0;
}
my_class.h:
class MyClass {
public:
void TestMethod();
};
my_class.cpp:
#include "my_class.h"
inline void MyClass::TestMethod() {
}
I try compiling with:
g++ main.cpp my_class.cpp
I get the error:
main.cpp:(.text+0xd): undefined reference to `MyClass::TestMethod()'
Everything is fine if I take away the "inline". What's causing this problem? (and how should I inline class methods? Is it possible?)
Thanks.
The body of an inline function needs to be in the header so that the compiler can actually substitute it wherever required. See this: How do you tell the compiler to make a member function inline?
7.1.2/4 of the Standard:
An inline function shall be defined in
every translation unit in which it is
used...
You use TestMethod in main.cpp, but it's not defined there.
... If a function with external linkage is
declared inline in one translation
unit, it shall be declared inline in
all translation units in which it
appears; no diagnostic is required.
You define (and hence also declare) TestMethod inline in my_class.cpp, but not in main.cpp.
The fix in this case is to move the function definition to the header file, either like this:
class MyClass {
public:
void TestMethod() {}
};
or like this:
class MyClass {
public:
inline void TestMethod();
};
inline void MyClass::TestMethod() {}
You've defined it as not inlined in the header file, while in the cpp file you're trying to define it as inline. That's a conflicted definition and it won't be able to find one from the other. Your header is where you really place the inline keyword.
However, I'd remove the inline keyword as it's really more of a suggestion to the compiler anyways. You really only need it when there's a free-floating function in the header and you don't want multiple definitions popping up in your code base.

Basic ODR violation: member functions in .h files

Disclaimer: This is probably a basic question, but I'm a theoretical physicist by training trying to learn to code properly, so please bear with me.
Let's say that I want to model a fairly involved physical system. In my understanding, one way of modelling this system is to introduce it as a class. However, since the system involved, the class will be large, with potentially many data members, member functions and subclasses. Having the main program and this class in one file will be very cluttered, so to give a better overview of the project I tend to put the class in a separate .h file. Such that I'd have something like:
//main.cpp
#include "tmp.h"
int main()
{
myclass aclass;
aclass.myfunction();
return 0;
}
and
// tmp.h
class myclass
{
// data members
double foo;
double bar;
public:
// function members
double myfunction();
};
double myclass::myfunction()
{
return foo + bar;
}
This however, amounts to the following compiler warning in my new compiler: function definitions in header files can lead to ODR violations. My question then is this: what is actually the preferred way of dealing with a situation like this? I guess I can just make tmp.h into tmp.cpp, but to the best of my understanding, this is the intended use of .h files?
Normally, a class definition goes in an ".h" file and its member functions' definitions go in a ".cpp" file.
If you want to define member functions in the header, you need to either declare them inline, or write them inside the class definition (which makes them implicitly inline).
Adding to the other answers:
This is a function definition:
double myfunction()
{
return foo + bar;
}
This is a function declaration:
double myfunction();
The purpose of the declaration is to declare the unique signature of the function to other code. The function can be declared many times, but can only have one definition, hence the ODR (One Definition Rule).
As a basic rule to start with, put function declarations in header files, and put definitions in source files.
Unfortunately in C++, things rapidly get more complicated.
The problem with just having the function signature available is that you can't easily optimise the code in the function, because you can't see it. To solve that problem, C++ allows function definitions to be put in headers in several circumstances.
You'll have to either use the inline keyword or put the definition of myclass in a .cpp file.
myclass.hpp
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( );
private:
double foo;
double bar;
};
#endif
myclass.cpp
#include "myclass.hpp"
double myclass::myFunction( )
{
return foo + bar;
}
Or you can define the function in the header (myclass.hpp) using inline.
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( );
private:
double foo;
double bar;
};
inline double myclass::myFunction( )
{
return bar + foo;
}
#endif
If you define the myFunction function in the class declaration then you can omit the use of the inline keyword.
#ifndef MY_CLASS_H
#define MY_CLASS_H
class myclass
{
public:
double myfunction( )
{
return foo + bar;
}
private:
double foo;
double bar;
};
#endif
ODR stands for One Definition Rule. It means that everything should have one and only one definition. Now, if you define a function in a header file, every translation unit that includes that header file will get a definition. That obviously violates the ODR. That's what the compiler is warning about. You have couple of ways to work around that:
Move the function declaration to a cpp file. That way there is a single definition.
Make the function inline. This means that there may be multiple definitions of this function, but you're sure that all are identical and the linker may use one those and ignore the rest.
Make the function static (doesn't apply to class-methods). When a function is static each translation unit gets it's own copy of the method, but they are all different functions and belong to one and only one compilation unit. So it's OK.

Inline functions in multiple translation units

Let's start with the following set of C++ files:
// my_class.h
struct MyClass
{
void my_func();
};
void MyClass::my_func()
{}
// f.h
void f1();
void f2();
// f1.cpp
#include "my_class.h"
void f1()
{
MyClass a;
a.my_func();
}
// f2.cpp
#include "my_class.h"
void f2()
{
MyClass a;
a.my_func();
}
// main.cpp
#include "f.h"
int main()
{
f1();
f2();
return 0;
}
I tried to compile this code with
$ g++ f1.cpp f2.cpp main.cpp
Obviously, the linker complained of duplicate symbol my_func:
duplicate symbol __ZN7MyClass7my_funcEv in:
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f1-962ae7.o
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f2-aef78c.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The next attempt I had was to move the function definition inside the class definition, so we get:
struct MyClass
{
void my_func()
{}
};
Running the same g++ command, the program compiles successfully. This is because functions defined in class definition are implicitly marked inline (§10.1.6 * 3).
The standard states:
A function declaration (11.3.5, 12.2.1, 14.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions specified in this section shall still be respected
Which seems somewhat in contradiction to what is written on cppreference.com:
Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred", [...]
So as far as I understand, having a function defined in the class definition makes it implicitly inline which does not necessarily mean that the compiler will choose to inline its body but will a definition of it in every translation unit. Is this correct?
The second question comes regarding template classes. Separating the declaration/definition of a template class is a problem, as described here so we can only have function definitions in the class definition which makes it implicitly inline, again, right? What is the impact of this?
Since we only have the choice of defining functions in class definitions when the class is a template, what is to be done about classes that are not template? Should we define function in source files and only keep the declaration in headers when possible?
So as far as I understand, having a function defined in the class definition makes it implicitly inline which does not necessarily mean that the compiler will choose to inline its body but will a definition of it in every translation unit. Is this correct?
Correct. When defined inside the class it is marked as inline and it is okay that that defenition is brought into multiple translation units. The compiler will handle that for you.
The second question comes regarding template classes. Separating the declaration/definition of a template class is a problem, as described here so we can only have function definitions in the class definition which makes it implicitly inline, again, right? What is the impact of this?
This is not correct. Templates are special. They aren't actually anything that will exist once the code is compiled. What a template is, is a recipe for stamping out a class or function. As such, they are implicitly inline as well to allow the template to be included in every translation unit that uses it so the compiler can stamp out a concrete class/function from it as needed. This means you can define class member functions outside of the class.
Since we only have the choice of defining functions in class definitions when the class is a template, what is to be done about classes that are not template? Should we define function in source files and only keep the declaration in headers when possible?
Typically you want to put your definitions in a cpp file. The benefit you get from this is you only need to recompile that one cpp file if you change the implementation of the functions. If they were in the header file then you need to recompile every cpp file that includes that header file which leads to longer build times.

What is a member function in c++?, does it contain a body?, is it defined in the .h or .cpp file? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm new in c++.
I'm required to define member functions. I am more familiar with java. I actually confused by the term "member function".
Do we have to define it in the header .h file or the .cpp file?
I am confused by the term of member function
Everything that belongs to a class or a struct is called a member of that class. Hence, we can have member functions. Below is a little exmaple:
class MyClass
{
public:
MyClass();
void myFunction();
int number;
}
Here you have myFucntion() and number members of MyClass
Do we have to define it in the header .h file or the .cpp file?
In C++, it doesn't matter where you define or declare a function or a class.
But keep in mind that putting declaring classes in .h files is better. It will lead to faster compilations of your project. So you should have something like:
// myClass.h
class MyClass
{
public:
MyClass();
void myFunction();
int number;
}
// myClass.cpp
myClass::myClass()
{
// this is a constructor
number = 10;
}
void myClass::myFunction()
{
// this is my function
cout << number;
}
Every function in C++ is a member
Member of a namespace. These are sometimes called "global functions", although that termis not completely correct. They consist of all functions in the global namespace and any functions in user defined namespaces, hence they are called namespace-scope functions.
Member of a class. These are called member functions (even though they are not the only functions that are members!). They can be further separated by non-static member functions and static member functions (I take it you know the difference of this from Java).
Alternate syntax:
class MyClass{
public:
void MyFunction(void); // prototype
}
MyClass::MyFunction(void){ // actual function
// code goes here
}
Think of member function as a method.
In Java, your method (member function) within a class might look something like:
public class MyClass {
public void MyMethod() {
// do stuff
}
}
This is very much the same in C++:
class MyClass
{
public:
void MyMethod();
}
As far as how I've been taught, you declare your class and its members in a header file (.h) and then define them in a .cpp file. You don't have to do it that way and can keep everything with your .cpp file. It's just a better practice to separate them.
in C++ does not matter ...
member functions are just functions inside class (or struct)
you can have headers
you can also have body only ...
if you separate headers and bodies into *.h(pp) and *.cpp files
then you can cross referencing more classes to each other
here some examples:
class C1
{
public:
int a,b,c; // some variables
void f0(); // header only
void f1() { c=a+b; }; // inline body only
friend void f2(); // not a member but can have access to class private things
friend void f3(C1 &x); // not a member but can have access to class private things
};
void C1::f0() { c=a+b; } // body(C1 member) ... can be in separate file
void f2() { C1 c1; c1.c=c1.a+c1.b; } // just function not a member
void f3(C1 &x) { x.c=x.a+x.b; } // just function not a member
if your not member function are accesing only public parts of class then they do not need to be friend.
also there are some restrictions for inline bodies on some compilers
like you can not use asm {} for example...
First, your question "Do we have to define it in the header .h file or the .cpp file?"
You can define (write code for) member functions in either, with different implications.
Any function defined in a header file needs to be an inline function (because it will be included to many .cpp files, and being inline means, this is ok). Luckily, if you combine declaration and definition and do it inside class {...}, they are automatically considered inline, so it "just works".
If you define the member function in a .cpp file, then you need to have the declaration inside class {...}. And if you want to use the class from many .cpp files, then it should go to a .h file, but it can also be earlier in the same .cpp file.
More explanation:
Member function is same as method. Also, for the purposes of this answer, function overloads (same name but different arguments, return value is not considered) are different functions.
In C++ there is separate declaration and definition, though they can be rolled into one. Any function is declared by having just ; instead of function body { /* ...code... */ }. If this declaration is inside a class {...} or struct {...}, then it's a member function. A function call is ok in code as long as there's declaration before the call. Then later on linker will complain if there's no actual function definition, that is a block of code to call. There can be any number of declarations for a function, but only one definition (except for inline functions, where compiler and linker assume duplicate definitions are all the same, so they better be or funny things can happen).
About .h and .cpp files: C++ (and C), .h files are eseentially copy-pasted to the .cpp file during compilation. You could remove the #include and copy paste the contents, and it would be exactly same thing for compiler. But from practical standpoint, definitions go to a .h file, and then they are included in may .cpp files, and because they are declarations, it's ok to have them as many times as you like. But actual definitions go to .cpp files, so they get compiled exactly once, so linker is happy.
Finally a bit about inline functions. If you have a member function definition inside class {...}, it is automatically considered to be inline. You include the same .h file with these inline definitions to many .cpp files, but it is ok because they are by default marked inline (and also, since the code is in same .h file, all definitions should be the same, unless you use some #ifdef preprocessor stuff wrong).
Example:
myclass.h
class MyClass {
void memberFunc1() {
// here is function declaration and definition combined,
// by default inline, so can be include to many .cpp
}
void memberFunc2(); // here's just declaration
}
myclass.cpp
MyClass::memberFunc2() {
// defintion of member function, not inline, must exist exactly once
}

How do C++ find the function declaration

I need help translating a concept from Java to C++.
In Java, when you create a class and give it methods (functions), you must define the function in that class so that it can be properly called by any class instance that might want to.
For example, in the class Employee you'd declare and define the method salaryRaise(int amount).
Whenever an Employee object wants to use it, it calls Employee.salaryRaise(i) and Java knows exactly where to find it - in the Employee class.
In C++, functions are declared in .h files and then defined somewhere else.
How does the compiler know where to find this method?
That is really the job of the linker, not the compiler. The compiler will call the function referencing a symbol that is yet undefined. The linker will then get the different translation units and resolve the symbols by name (that is, the mangled names that encodes additional information as the namespaces, types of the arguments...)
You declare the function in the header (.h) file. That header file then gets #includeed in any other files where you need to use the function. This satisfies the compiler, because it knows the signature of the function and how to call it.
The function is then defined in the source (.cpp) file. The source file includes it's own header file, so that when you compile it, you end up with an object file containing the complete compiled code for that function.
The linker then links any parts of your code where you've called the function (i.e. the files where you included the header), with the actual code for that function.
EDIT with example:
Foo.h:
#ifndef FOO_H
#define FOO_H
class Foo
{
public:
int fooFunction(double a);
};
#endif
Foo.cpp:
#include "Foo.h"
int Foo::fooFunction(double a)
{
// Function definition
return 1;
}
Compiling Foo.cpp generates Foo.obj which contains the complete definition for fooFunction. So far so good.
Bar.h:
#ifndef BAR_H
#define BAR_H
#include "Foo.h"
class Bar
{
public:
void barFunction();
};
#endif
Bar.cpp:
#include "Bar.h"
void Bar::barFunction()
{
Foo foo;
int returnValue = foo.fooFunction(2.0);
}
Bar.cpp includes Bar.h which in turn includes Foo.h. When Bar.cpp gets preprocessed therefore, the declarations for Foo::fooFunction are inserted at the top of the file. So, when the statement int returnValue = foo.fooFunction(2.0); is compiled, the compiler knows how to emit the machine instructions to call fooFunction because it knows the type of the return value (int) and it knows the types of the parameters (a double, and an implicit this pointer for the foo object). Because no function definition was provided, the function will not be inlined (inlining means the entire code for the function is copied into the point at which it is called). Instead, a pointer to the memory address of the function is used to call it. Because a pointer is being used, the compiler doesn't care about the definition - all it needs to know is "I need to call a function X at memory location Y with parameters A and B, and I need to have an int sized memory section ready to store the return value, and I'll assume that the code at that address knows how to perform the function". However, the compiler has no way to know what the address of that function will be in advance (because the function definition lives in a separate .cpp file and will be part of a separate compilation job AKA translation unit).
That's where the linker comes in. Once all the translation units have been compiled (which could be in any arbitrary order), the linker goes back to the compiled code for Bar.cpp and links the two together by filling in the address for the now compiled definition of fooFunction at the point at which it is called in Bar.cpp, thus making the compiled code fully executable.
In C++, functions are declared in .h files and then defined somewhere else. How does the compiler know where to find this method?
Because you tell it where to find it when you provide the definition of the method.
Consider a hypothetical header file:
class Gizmo
{
public:
bool Foo();
};
Now we will define the Foo method above in another CPP file:
bool Gizmo::Foo()
{
return true;
}
Here's the paraphrased dialogue you have with the above definition:
Ok, compiler. I'm defining a function which returns a bool. The
function is part of the class Gizmo, and the function is named Foo.
The function takes no parameters. The definition of the function is:
return true.
The scope resolution token :: separates a name of an enclosing class and the name of the function.
If you had left that Gizmo:: bit out, and instead wrote:
bool Foo()
{
return true;
}
The you would still be defining a function named Foo which takes no parameters and returns a bool, but now instead of defining it to be part of Gizmo, you are defining it to be on it's own. A so-called "free function" or "global function." This would compile just fine, but you would get an "unresolved external" linker error if some other code somewhere was trying to use Gizmo::Foo().
When the compiler transforms your source to binary, it usually builds intermediary files (aka object files) that contain (among other things) the member functions of a class.
At the time of linking the intermediary files are translated into machine code. If all member functions used can be resolved at that time, all is good, otherwise you get a linking error.
This way, you can place the definition of member functions anywhere in the project -- as long as the linker finds what it needs, it can build the binary. It is not advised, however as this approach will make reading/understanding the class purpose/mechanic harder for humans
A compiler will typically have a compilation stage and a linking stage. The compilation stage compiles source files into object files. The linking stage will collect the object files and create an executable image. During the linking stage, symbols that were left unresolved in the compilation stage get resolved. This is not much different for either Java and C++. For example, it is how a Java class can call methods on a different Java class.
In C++ you determine the body by class name followed by :: and then method declaration:
class Employee
{
void salaryRaise(int amount); // Now, compiler knows this method belongs to
// the class Employee
};
Then you can define the body:
void Employee::salaryRaise(int amount) // Now, compiler knows everything about
{ ^^^^^^^^^^ // definition of the method
}
For generating object files (and executable binary), you have to pass the .cpp files to the compiler(actually the linker). Therefore everything is visible to the compiler.
In your header file, you prototype/forward declare the class like this.
class Foo
{
private:
int m_Fooint;
int m_Fooint2;
public:
Foo(int a, int b);
int getFooTotal();
};
Then you would define the member functions like this
Foo::Foo(int a, int b) // prototypes names don't have to be the same
{
Foo::m_Fooint = a;
Foo::m_Fooint2 = b;
}
int Foo::getFooTotal()
{
return Foo::m_Fooint + Foo::m_Fooint2;
}
Besides the constructor and destructor, you need to have the data type. Even if it's void and not returning anything.
So you might have something such as
float Foo::getSomeFloat();
or
double Foo::getSomeDouble();
or you can even return an object
OtherClass Foo::getOtherClassObject();