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.
Related
I am trying to get the compiler to react to some code that I believe does not violate the one-definition-rule in C++. Inside a header file, I have two declarations: one for a struct and one function, like this:
struct TestStruct {
int a;
double d;
};
int k();
Then I intentionally include the header file twice in another file with main() in it, to see what happens.
To my surprise, the compiler complains about multiple definitions for the struct. I was expecting the compiler not to raise any multiplicity error at all since both the struct and function have pure declarations.
It is only after I put the struct in a header-guard that the compiler stops complaining. But, there is no memory allocated for the struct. It is not a definition. Then why is the compiler mad?
You can't define a struct more than once in a single translation unit.
You can define it in several translation units, but then the definitions have to be the same. (Source: cppreference/ODR).
To avoid this problem, you need to have an include guard in your header. It will silently prevent the header from being included more than once in each translation unit.
Use include guards (or if available with your compiler) pragma once.
#ifndef PATH_TO_FILE_FILENAME_H
#define PATH_TO_FILE_FILENAME_H
struct TestStruct {
int a;
double d;
};
int k();
#endif
or (much better if available!)
#pragma once
struct TestStruct {
int a;
double d;
};
int k();
Also might be worth using namespaces to avoid polluting the global namespace
#pragma once
namespace Test
{
struct TestStruct {
int a;
double d;
};
int k();
};
Note that to avoid muldefs you'll also need to declare k() inline should you decide to provide its definition in the header (this can be unavoidable sometimes should you need to use templates and not specify explicit template parameters).
#pragma once
namespace Test
{
struct TestStruct {
int a;
double d;
};
template<typename T>
inline int k<T>() // This now has to be inline or static.
{
// Some implementation
}
};
Edit: On an aside, the difference between a declaration and a definition for a struct/class isn't much different from a function:
void TestFunction(); // The compiler now knows there's a function called TestFunctionand can attempt to link the symbol information to its implementation somewhere in the compilation unit.
Where in this case we're not implementing the meat and bones of the function, just saying it exists and since the compiler knows the signature (or what the function promises to take and return) it can continue happily. In TestStructs case the forward declaration (without implementation) would be
class TestStruct;
I find it a very appealing programming style define all the methods of a struct/class directly inline in the struct, eg only define structs this way:
"A.hpp"
class A;
"A.cpp"
class A
{
A() = default;
void method() { }
};
rather than
"A.hpp"
class A
{
A();
void method();
};
"A.cpp"
A::A() = default;
void A::method() { }
This means putting classes/struct definitions in a code file and only including declaration in header files.
However, this runs into the problems when the compiler would need to know the struct/class layout in other code files.
Is there a programming style that supports this? Perhaps only getting and setting fields through getters/setters? This way would however lead to large amounts of boilerplate.
Just including the struct/class definition in the header file leads to issues with mutually recursive header files, unless one explicitly puts the declarations in another.
I can achieve this programming style in a language like D with a module system, but how does one achieve it in C++?
What are you doing is called forward declaration.
You will be not able to do anything (f.e. call methods, create instances) with this class in all other translation units, except one .cpp file, where you define it. So, this idea is completely useless and bad. And you will get a boatload of linker errors.
So, you need to either stick to style #2. Or define inline methods in header file, like this
struct A {
A() {} // something
int func() { /* function body */
}
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
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
}
I would like a function that is not a member of a class and is accessible from any class.
I assume I would have to #include the header file where the function is declared, but I don't know where to define such a global function.
Are there good reasons against having such a function in the first place?
you need a body (in a cpp file):
int foo()
{
return 1;
}
and a definition/prototype in a header file, which will be included before any use of the function:
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
int foo();
#endif
then using it somewhere else:
#include foo.h
void do_some_work()
{
int bar = foo();
}
or use an inline function (doesn't guarantee it'll be inlined, but useful for small functions, like foo):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
inline int foo()
{
return 1;
}
#endif
alternatively you can abuse the C-style header based functions (so this goes in a header, the static forces it to exist in a single compilation unit only, you should avoid this however):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
static int foo()
{
return 1;
}
#endif
What you are calling global function is usually called a free function and they are A Good Thing.
You would define it just like a class' member function, but outside of that class' scope.
double squared(double x) {
return x*x;
}
Simple functions you can define with the inline keyword in the header file, or just declare it there
double squared(double x);
and put the implementation (first example) into the *.cpp file.
In a header file:
// someheader.h
#ifndef MY_GLOBAL_FUN
#define MY_GLOBAL_FUN
void my_global_fun();
#endif
In an implementation file:
#include "someheader.h"
void my_global_fun()
{
// ...
}
In other files that require that function:
#include "someheader.h"
void f()
{
my_global_fun();
}
Free functions like this are useful and there are not many arguments against using them. Depending on your use case, its likely appropriate to put these functions in a specific namespace to avoid name collision with other libraries you may be using.
Think of main(). The function is kind of just...there. It's not within any class, struct or namespace. You just declare and give it a body. Of course, in the case of functions that are not main, it's best to put a prototype in a header and the define it in a .cpp file.
Remember, C did not have classes and structs could not hold member functions. There was nothing wrong with free functions then and there isn't now.
You have to declare its prototype in header file and define it in implementation file.
//file.h
void foo();
//file.cpp
void foo ()
{}
To shortly answer your second question, Global functions are needed when they are used by several different classes and types in a generic way. For example math functions.
Otherwise, in general you may avoid so many global functions. Also you should avoid having a static local member or global data associated with such function (so that you don't have to worry about thread safety).
In addition to the answer by #Necrolis, the use of static is deprecated in favour of unnamed namespaces. However, use of unnamed namespaces and static both creates separate copies for each translation unit which increases the size of binary. The use of inline is better than both of these in this sense.
These solutions allow for more usage specific optimisations by compilers but are less instruction cache friendly compared to definition in a source file and then linking.