I'm writing utility functions for my current project.
Right now, I have a utility.h header which defines a class with static methods:
#pragma once
class Utils
{
public:
static int firstFunc()
{
return 0;
}
static bool secondFunc()
{
return false;
}
};
This header is included every time I need to use such functions (in two translation units at the moment) and it works just fine.
Now, after a code review, it was suggested to replace this class by C-style functions. My naive first attempt:
#pragma once
int firstFunc()
{
return 0;
}
bool secondFunc()
{
return false;
}
failed to link, returning a multiple definition of function error.
I understand why this happens: the header utils.h, which contains the function definitions, is present in two different compilation units: the linker doesn't know which definition to use.
I know that the solution is to move the definitions to a dedicated utils.cpp and leave only the declarations in the header.
My question now is: why didn't this happen when I had the class with static methods, when I still had multiple definitions of the same class in different translation units?
Functions definitions (static or not) that are written directly inside the class body are implicitly inline. Had you separated the definitions:
#pragma once
class Utils
{
public:
static int firstFunc();
static bool secondFunc();
};
static int Utils::firstFunc()
{
return 0;
}
static bool Utils::secondFunc()
{
return false;
}
... you'd have witnessed the exact same multiple definition error.
Also, these are not "C-style functions", just free (non-member) functions. C++ has nothing against free functions ;)
Related
In one of my classes header file Lfo.h, I have a class definition where I put the member function definition out of the class (It might be better to have a separate .cpp file but it should be ok put here?):
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Then I have another class called CVibrato:
// Vibrato.h
class CVibrato
{
public:
static int create (CVibrato*& pCVibrato);
private:
CVibrato();
};
and the .cpp file (in the cpp file, I include Lfo.h because later on the vibrato class will have a lfo member but I haven't implemented right now):
// Vibrato.cpp
#include "Lfo.h"
#include "Vibrato.h"
int CVibrato::create(CVibrato *&pCVibrato)
{
pCVibrato = new CVibrato();
return 0;
}
CVibrato::CVibrato()
{
}
Then I want to create a instance of vibrato class in main()
#include "Vibrato.h"
#include "Lfo.h" // if comment this line out there will be no error, why is that?
int main()
{
CVibrato *vibrato = 0;
CVibrato::create(vibrato);
return 0;
}
However I get a 1 duplicate symbol for architecture x86_64 error. What is duplicated? It seems the reason is in Lfo.h, I put the definition of the member function outside of the class, if I put it inside, the program runs properly. But I cannot understand. In c++, aren't we allowed to do this? By the way, if one of my class (in my case vibrato) is going to have a class member of another class (in this case lfo), should I include the header file of member class in .h (vibrato.h) file or .cpp (vibrato.cpp) file?
Classes are declarations. No code is produced from a declaration. Even if you have a member function in the class, it is treated as if an inline by the compiler. Function bodies can be put in a header but should always be declared as inline. The compiler may not actually inline it, but it will treat it as a single instance for code creation.
Any time you:
void function( ) { }
Code is created for that function. If a header is included more than once the compiler is told to create the code more than once. But all functions must have unique names! So you get the duplicate error. That is why code generating lines belong in the .cpp files.
'inline' tells the compiler not to create immediate code but to create the code at the usage point.
You can't put class method definition directly in a header file, unless you explicitly mark it as inline. Like the following:
// Lfo.h
class CLfo
{
public:
inline static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Or,
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
inline int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
If I have a class similar to this :
//body.h
class Body
{
static int i;//line 1
};
int Body::i=2;/line 2
and a class like this:
//ball.h
#include <body.h>
//line 3
class Ball:public Body
{
int f();
};
and in ball.cpp :
int Ball::f()
{
return 1;
}
this results in multiple definition of i.
I tried putting extern in line1,line2 and defining it in line 3 and still having the same error, I also searched the web, most of the results I find talks about a variable declared solely(not in a class) while I have a static class variable.
I understood that extern is opposite to static but making i extern in line1 didn't help, also I saw many questions in SO , this talks about namespaces which I don't want, this doesn't address my issue.
As A note, there is no body.cpp, there are classes other than Ball that inherits body and there is main.cpp which will access all the children classes.
So what to do to be able to use Body::i outside body.h ?
PS
all classes are surrounded in header guards .
Create another translation unit Body.cpp and move the definition there
int Body::i=2;
Even with header guards, as you mention to have them, the definition appears in multiple translation units, hence the multiple definition error.
In your particular case the static class member is a primitive, and can be initialized at the point of declaration alternatively:
class Body {
static int i = 2;
};
You should not define the static member in the header. You need to make a source (.cpp) file for it:
body.h (declare statics but don't define)
class Body
{
static int i; // only declare
};
// int Body::i=2; // do not define it here
body.cpp (define statics here)
#include "body.h"
int Body::i = 2; // now we define it
namespace n1 {
namespace n2 {
...
int myfunc(void)
{
return 1;
}
class myclass {
..
};
}
}
I thought it is possible to define a function this way, and access it both from 'myclass' and its derivatives. However gcc doesn't even want to compile this code:
multiple definition of `n1::n2::myfunc()'
This function is the only one here, what am I missing?
Thanks.
You need to either mark the function inline to avoid breaking the one definition rule, or place the implementation in a .cpp file, and leave only the declaration in the header.
I have a question concerning inlining methods.
I am using a library developed for collision models. One header file responsible for graphic interface contains declaration and implementation of the functions but the functions are not inlined. Therefore, it is impossible to include those functions in several translation units.
As an illustration here is a dummy code I designed for illustration :
LivingBeing.h
#ifndef LIVINGBEING_H
#define LIVINGBEING_H
class LivingBeing
{
public:
LivingBeing(double _size);
void breathe();
private:
double size;
};
//////////////
LivingBeing::LivingBeing(double _size)
{
size = _size;
}
void LivingBeing::breathe()
{
// do something
}
#endif
Forest.h
#ifndef FOREST_H
#define FOREST_H
#include "LivingBeing.h"
class Forest
{
public:
Forest(int _numberLivingBeings);
private:
int numberLivingBeings;
};
#endif
Forest.cpp
#include "Forest.h"
Forest::Forest(int _numberLivingBeings)
{
numberLivingBeings = _numberLivingBeings;
// Call LivingBeing constructor, methods etc...
}
Main.cpp
#include "Forest.h"
int main()
{
Forest forest = Forest(10);
return 0;
}
This code does not compile unless I add the inline keyword in front of the constructor LivingBeing and the method breathe. The error message is :
1>main_test.obj : error LNK2005: "public: __thiscall LivingBeing::LivingBeing(double)" (??0LivingBeing##QAE#N#Z) already defined in Forest.obj
1>main_test.obj : error LNK2005: "public: void __thiscall LivingBeing::breathe(void)" (?breathe#LivingBeing##QAEXXZ) already defined in Forest.obj
1>C:\Users\******\Documents\Visual Studio 2010\Projects\TutorialChronoEngine\Debug\Test_3.exe : fatal error LNK1169: one or more multiply defined symbols found
My question is : what is the drawbacks of inlining methods ? The real library I am using is pretty large, I would like to inline methods from a specific file (in my example it would be LivingBeing.h) so that it is possible to use those methods in several .cpp files. What am I risking by changing the source file as such ?
Thanks a lot
You are defining functions (LivingBeing::LivingBeing and LivingBeing::breathe) in a header, which means there will be a definition in each translation unit that includes that header. This breaks the One Definition Rule (ODR), hence the link error.
You have three options:
Move the function definitions into a source file so they are only defined once; or
Declare them inline to allow multiple identical definitions; or
Move the definitions inside the class definition, which implicitly makes them inline.
what is the drawbacks of inlining methods ?
Possibly increased compilation time and executable size; but you'd need to measure to see whether there's any noticable difference.
A less stable API - client code will need recompiling whenever any inline function changes.
The possibility of accidentally breaking the ODR, for example if a function contains macros which might have different expansions in different translation units.
Just because a method is defined in a "source" file (.c/.cpp) doesn't mean it won't be inlined... link-time operations may perform that optimization. Oppositely, just because a method is declared and implemented as inline in a header file doesn't mean it will be inlined. In general, I define methods in a header file if they are very simple, e.g. int getWidth() const { return width; }, or MyObj* getNext() { return internal_itor ? internal_itor->next : 0; }
i have two questions that are fairly small and related so i will put them both in the same question.
i have been experimenting with classes and i was attempting to access a class in another file that wasn't in a class so for example.
//class 1 .cpp
void Class1::function1()//another error
{
function()
}
//main.cpp
void function()
{
//stuff happens
}
is there a way to-do this? or would i need to add this function to a class to get it to work. also how would you go about creating a function that receives a function as it parimetre? for example function(function2())
i am simply trying to access a function from a class as it would make my code easier to use later if the function that i am using doesn't get added to a class. with regards to the seconds question i which to create a function that receives a time and a function as an argument. it will wait for the specified time then execute the program
How to access a function in another file?
Depends on the type of function, there can be to cases:
1. Accessing class member functions in another file(Translation Unit):
Obviously, you need to include the header file, which has the class declaration in your caller translation unit.
Example code:
//MyClass.h
class MyClass
{
//Note that access specifier
public:
void doSomething()
{
//Do something meaningful here
}
};
#include"MyClass.h" //Include the header here
//Your another cpp file
int main()
{
MyClass obj;
obj.doSomething();
return 0;
}
2. Accessing free functions in another file(Translation Unit):
You do not need to include the function in any class, just include the header file which declares the function and then use it in your translation unit.
Example Code:
//YourInclude.h
inline void doSomething() //See why inline in #Ben Voight's comments
{
//Something that is interesting hopefully
}
//Your another file
#include"YourInclude.h"
int main()
{
doSomething()
return 0;
}
Another case as pointed out by #Ben in comments can be:
A declaration in the header file, followed by a definition in just one translation unit
Example Code:
//Yourinclude File
void doSomething(); //declares the function
//Your another file
include"Yourinclude"
void doSomething() //Defines the function
{
//Something interesting
}
int main()
{
doSomething();
return 0;
}
Alternately, a messy way to do this can be to just mark the function as extern in your another file and use the function.Not recommended but a possibility so here is how:
Example Code:
extern void doSomething();
int main()
{
doSomething();
return 0;
}
How would you go about creating a function that receives a function as it parameter?
By using function pointers
In a nutshell Function pointers are nothing but pointers but ones which hold address of functions.
Example Code:
int someFunction(int i)
{
//some functionality
}
int (*myfunc)(int) = &someFunction;
void doSomething(myfunc *ptr)
{
(*ptr)(10); //Calls the pointed function
}
You need a prototype for the function you want to call. A class body contains prototypes for all its member functions, but standalone functions can also have prototypes. Typically you organize these in a header file, included from both the file which contains the function implementation (so the compiler can check the signature) and in any files which wish to call the function.
(1) How can the `class` function be accessible ?
You need to declare the class body in a header file and #include that wherever needed. For example,
//class.h
class Class1 {
public: void function1 (); // define this function in class.cpp
};
Now #include this into main.cpp
#include"class.h"
You can use function1 inside main.cpp.
(2) How to pass a function of class as parameter to another function ?
You can use pointer to class member functions.