This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
reincluding header in implementation
What I am wondering is that it is common practice to not use using namespace xxx in a header file as not to pollute the global namespace.
How does this go for #includes?
If I have foo.h and foo.cpp.:
//Foo.h
#ifndef FOO_H_
#define FOO_H_
#include <string>
class Foo
{
public:
Foo(std::string * a, std::string * b);
virtual ~Foo();
};
#endif /* FOO_H_ */
//Foo.cpp
#include <string>
#include <Foo.h>
Foo::Foo(std::string * a, std::string * b)
{
// TODO Auto-generated constructor stub
}
Foo::~Foo()
{
// TODO Auto-generated destructor stub
}
Would I really need to #include <string> in both files? Would including it only in the .h or .cpp suffice? (I know both will work, but what is advisable?)
edit, a bit more background information regarding my question.
If I would be using certain classes in my header file (either as variables or method arguments) I would forward declare them in the header file and only include the header file itself in the source file. But this will not work for most STL libs because you can't forward declare class-templates?
... because you can't forward declare class-templates?
class templates can be forward declared - like non template classes:
// forward declaration
template <typename T>
class C;
However, as #AlexandreC stated in comments, for std::string it would be quite complicated, because std::string is typedef from template <typename,typename,typename> basic_string;.
I write it would be complicated, if it would be allowed. And it is not allowed, see:
http://www.gotw.ca/gotw/034.htm
https://stackoverflow.com/a/10290176/1463922
According to the C++11 standard, 17.6.4.2.1:
The behavior of a C++ program is undefined if it adds declarations or
definitions to namespace std or to a namespace within namespace std
unless otherwise specified.
So, no choice but include <string> in header file for std::string.
For your main question - I would include in source and header files, unless I was pretty sure it would be always included in header file and never removed...
Related
I am currently working on a project where we have a shared set of headers. Now we want add some private fields without having to put those declarations directly in the shared headers.
Someone brought up the following:
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
Inside the _private.hpp headers we would then place the private fields for that class. When there are only default datatypes (int, bool, etc) this works fine(ish). But as soon as you put an include inside the _private.hpp file, for example #include everything breaks.
It is giving the following error expected unqualified-id before ‘namespace’ which as I understand is quite logical, since you're trying to define a namespace inside of a class.
Example _private.hpp file
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Now my question is, is there any way to trick the preprocessor, or somehow get the same results with a different solution?
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#if __has_include("foo_private.hpp")
#include "foo_private.hpp"
#endif
};
}
If that code is including a file that looks like this:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
Then you end up with this (though in reality, the #includes themselves would resolve to the contents of <string>, etc.):
namespace something {
class Foo {
public:
Foo();
void doFoo();
private:
#ifndef DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#define DUMMY_PRIVATE_TEMPLATE_INCLUDES_FOO_PRIVATE_HPP
#include <string>
int mySecretNumber;
std::string mySecretString;
#endif
};
}
Perhaps that shows your issue? You're including "string" in the middle of your class, but it needs to be included at the global namespace scope of your file.
Instead, include string at the top of the outer header, don't use include guards in the private header, and only put the body of the code you want pasted into your class into that private header. For that reason, you might not call it a ".hpp" file but something else to make it clear it's not a normal header.
Additionally, the __has_include feature seems dubious, because if your private header is missing you probably do not want it to compile to an empty class.
Worse, if you compile some translation unit that finds the header, and then compile another translation unit that does not find the private header, you will end up with two different definitions of your class, violating the One Definition Rule -- which is undefined behavior, no diagnostic required. Really nasty stuff (assuming your builds succeeds at all.)
I'm not a big fan of this kind of hiding, as it will make it hard for editors to properly show your code, to colorize and index your private header, or otherwise work with the code in a normal way. You might consider looking at the PIMPL idiom for hiding the implementation of a class in its .cpp file, so users of the header do not have to see it at all.
I'm trying to create a library for a school work, and I've been wondering if it is safe to declare a templated class on the main header file containing the class definition and method declarations, but then separating the method definitions in a different header file?
Because I have been able to do this in my example below, but I don't know if it will cause me some problems in the long run.
main program
// main.cpp
#include <iostream>
#include "declaration.hpp"
int main()
{
card<int> a(5);
std::cout<<a.getID()<<'\n';
return 0;
}
main header file
in this header file, only the class definition and the declaration of the method getID() is written but not it's definition, and by the end of the class I included the other header file that contains the method definitions.
// declaration.hpp
#ifndef DEC_HPP
#define DEC_HPP
#include <iostream>
template<typename T>
class card
{
public:
T id;
card(const int id) : id(id) {}
T getID();
};
#include "definition.hpp"
#endif
method definitions
This header file contains the method definition of getID() from the main header.
I also included the "declaration.hpp" in this header, and this is the part where I'm not so sure of, because I included both files together with each other.
// definitions.hpp
#ifndef DEF_HPP
#define DEF_HPP
#include <iostream>
#include "declaration.hpp"
template<typename T>
T card<T>::getID()
{
return id;
}
#endif
I have compiled this program and it's working on my machine, but I just wanted to know if this way of isolating my code will cause me some errors in the future, I don't want to put my templated class definitions in a cpp files because I find it hard to maintain.
This is indeed a better approach because it makes your code look simple and better. Moreover, it is the main reason why header file is used.
Your main header file will simply tell that what functions/classes are you using and without even viewing your code, anyone can guess if you are working correctly or not.
There wont be any safety issues at all.
I have an interface ver as
// ver.h
class ver
{
public:
virtual void func()=0;
};
Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);
#endif
and
// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_b
);
#endif
Now the implementations
//ver1.h
#include "test\header.h"
class ver1:public ver
{
public:
FuncPoint f;
};
and
//ver2.h
#include "test2\header.h"
class ver2:public ver
{
public:
FuncPoint f;
};
and ver1.cpp and ver2.cpp will be using the respective f
Now the polymorphic behavior comes into play here
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return new ver1();
else
return new ver2();
}
Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile.
On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.
I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.
A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.
Is there some other better way to fix this?
EDIT:
I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).
Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):
//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a);
class ver1 : public ver
{
public:
FuncPoint_a f;
static ver1 *create();
};
Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.
Following your code it would become:
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return ver1::create();
else
return ver2::create();
}
In this way the two colliding headers will never be included in the same file.
I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.
I've been doing some reading into designing template code have a question about it. Most of the solutions to problems relating to designing code as templates seem to either be:
Put definitions of prototypes into the header file
Use the export keyword like this (which requires an extra compiler option)
Specifically lay out how the templates will be used in the .cc/.cpp file.
For example:
// File: foo_impl.cc
// We're working with Class Foo
#include "foo.cc"
template class Foo <int>;
template class Foo <string>;
// etc.
None of these methods seem very effective. Unless if I'm missing something, they don't seem to offer the ability for a user to simply import the header file and link the template code (in a .cc file) without doing extra work. I was wondering if people could take a look at what I'm doing with my own code and tell me if these violate some kind of best practices protocol or if they could cause an issue that I'm just not seeing. Here's what I've been doing...
In main.cc:
#include <iostream>
#include "foo.h"
using namespace std;
int main (void) {
Foo <string> f ("hello world");
string s = f.get ();
cout << s << endl;
return 0;
}
In foo.h:
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get ();
private:
T data;
};
#endif
#include "foo.cc"
In foo.cc:
#ifndef FOO_CC
#define FOO_CC
#include "foo.h"
template <class T>
Foo :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
#endif
I've been able to compile the code with all warnings in gcc 4.1.2. Thank you!
I personally prefer to put the declaration (.h) in a separate file from the definition (your .cc file). Also, I'd avoid including the .cc file in the .h file. Methods in a .h file should only be inline methods.
Let's say in your example you also had a header file (bar.h) that simply declares a class that has a Foo data member.
Every time you would modify the definition of the Foo class, you would cause a recompile of anyone who includes bar.h, even tough they couldn't care less about the definition of Foo. However, bar.cpp is probably where you actually implement stuff and that file DOES need to include the implementation of your template. This seem trivial in small projects, but becomes a source of headaches in big projects that constantly recompile files for no reason. I've seen people throwing SSDs and Incredibuild at stuff that could be fixed by simple forward declares and better header management.
Personally, I use .imp.h for the implementation of my templates. Including cc files or cpp files seems yucky to me.
For example ( sorry for compilation errors. ;) )
// foo.h
#ifndef foo_h
#define foo_h
template< typename T >
struct Foo
{
Foo( T value );
void print();
T _value;
};
#endif
//foo.imp.h
#ifndef foo_imp_h
#define foo_imp_h
#include "foo.h"
#include <iostream>
template< typename T >
Foo< T >::Foo( T value ) : _value( value ) {}
void Foo< T >::print() { std::cout << _value << std::endl; }
#endif
// bar.h
#ifndef bar_h
#define bar_h
#include "foo.h"
struct Bar {
Foo< int > _intFoo;
Foo< double > _doubleFoo;
void print();
};
#endif
// bar.cpp
#include "bar.h"
#include "foo.imp.h"
void Bar::print()
{
_intFoo.print();
_doubleFoo.print();
}
// foobar.cpp
#include "bar.h"
void foobar()
{
Bar bar;
bar.print();
}
Had the defintion of foo be included in or by foo.h, bar.cpp and foobar.cpp would have been recompiled. Since only bar.cpp is concerned with Foo's implementation, splitting the defintion and declaration of Foo in two files and not having foo.h include foo.imp.h at the end saved me a recompile of foobar.cpp.
This is something that happens all the time in projects and can be very easily avoided by following the .h/.imp.h rule I explained above. The reason you never see this in stuff like STL or boost is because you are not modifying those files. It doesn't matter if they are in one or two files. But in your own projects, you will be constantly modifying the definitions of your templates and this is how you reduce recompilation times.
If you already know beforehand which types are actually going to be used with your template, than do not even bother with the .imp.h file. Put everything in a .cpp and do this at the end
// foo.cpp
// Implementation goes here.
// You might need to put something in front so that it gets exported from your DLL,
// depening on the platform
template class foo< int >;
template class foo< double >;
Lets start with basic ideology of .h and .cc files. When building libraries, the idea is to share only your header files and not your implementation (mean .cc files). This is also the basics OOP's encapsulation, abstraction etc, to hide the implementation details.
Now templates in C++ violates this principle, bcoz C++ is a compiled language. And compiler generates all the needed code during compilation. Now to adhere to OOP we end up with fragile templates which not 100% generic in nature.
Keep declaration and definitions separate (SHARING implementation)
If you are just want to keep things clean and in order, then you can include your implementation file in another header. I think it should be header file as this goes with basic convention that we share .h files and we keep .cc files not to be shared (until you are sharing the code itself). Here is how the files look.
foo.h
This is simple file with including foo_impl.h.
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get();
private:
T data;
};
#include "foo_impl.h"
#endif
foo_impl.h
This one is bit different from the norms. Here we are not guarding the header file content. Instead we will raise an error if some one included foo_impl.h directly (which in our case does not make sense).
#ifndef FOO_H
#error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
#endif
template <class T>
Foo <T> :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
Now if some one tries to include foo_impl.h directly will get error like:
foo_impl.h:2:2: error: #error 'foo_impl.h' is not supposed to be included directly. Include 'foo.h' instead.
PROS:
Separation of concerns, implementation and declarations are in separate files.
Safe guarding implementation file avoid accidental inclusion.
The header file used to include is not bloated with implementation code.
CONS:
As mentioned above, have to share the implementation.
NOTE: For not sharing code for templates, I think you already know that you have to declare all possible types in the which the end user can use it.
Including .cc files is bad news and defeats the purpose of separating implementation from declaration.
Define templates in headers:
#ifndef FOO_H
#define FOO_H
template <class T>
class Foo {
public:
Foo (T);
T get ();
private:
T data;
};
// implementation:
template <class T>
Foo :: Foo (T stuff) {
data = stuff;
}
template <class T>
T Foo <T> :: get () {
return data;
}
#endif
If you really prefer 2 files then make the second one a .h too. Name it foo_impl.h or something.
It is common to affect the seperation of interface and implementation for templates by #includeing the implementation of the templates at the end of the header, but there are three problems with how you are doing it:
You're including the .h file in the .cc file. Don't; there should be nothing but function definitions in the implementation file.
You're .cc file should not be named .cc, it should be named .template or something similar to let people know that it should not be compiled (like headers should not be compiled)
The #include "foo.cc" in foo.h should be inside the include guards, not outside.
Done this way, there is no extra work for the user to be done. All you do is #include the header, and you're done. You don't compile the implementation.
Since you are including foo.cc in foo.h, you'll make your life simpler by putting all the code into foo.h and getting rid of foo.cc. There is no advantage to be gained from splitting the code into two pieces.
export keyword is deprecated in c++11. So, you will end up with deprecated code. You put your defintions in the header file itself.
I admit I'm a bit naive when it comes to includes. My understanding is that if you use it in your class you either need to include it or forward declare it. But then I was going through some code and I saw this:
// file: A.cpp
#include "Helper.h"
#include "B.h"
#include "C.h"
#include "A.h"
// ...
// file: A.h
B b;
C c;
// ...
// file: B.h
Helper h;
// ...
// file: C.h
Helper h;
// ...
Can someone explain to me why B and C does not need to include Helper? Also, what are the advantages/disadvantages to organizing includes this way? (Besides the obvious less typing.)
Thanks.
When you #include some header (or other) file into a .cpp file, that #include statement is simply replaced by the content of the header file. For example:
//header.h
int i;
float f;
// file.cpp
#include"header.h"
int main()
{}
After preprocessing stage, file.cpp will look like,
int i;
float f;
int main()
{}
Can see this in g++ using g++ -E file.cpp > TEMP, which shows you just the preprocessed files.
In your present question context, you must have #include helper.h in/before B.h and C.h as they appear before and you declare an object of those types.
Also, it's not good practice to rely on the arrangement of header files to get the code working, because once you alter arrangement little, the whole hierarchy collapses with several compilation errors.
Instead #include everything in the file if you are using it and you can use the #ifndef guards to avoid multiple inclusion:
//helper.h
#ifndef HELPER_H
#define HELPER_H
// content of helper file
#endif
If the class definitions for B and C don't actually refer to any of the members of the Helper class, then the compiler doesn't need to see the full definition of the Helper class in their header files. A forward declaration of the Helper class is sufficient.
For example, if the definition of the B class only uses pointers or references to Helper, then a forward reference is recommended :
class Helper;
class B {
// <SNIP>
Helper* helper;
// <SNIP>
void help(const Helper& helper);
// <SNIP>
};
If the definition of the B class uses an instance of the Helper class (ie. it needs to know the size of the Helper instance), or otherwise refers to the definition of the Helper class (in template functions eg.), then you need to make the full definition of the Helper class visible (most likely by including the header file that defines the Helper class) :
#include "helper.h"
class B {
// <SNIP>
Helper helper;
// <SNIP>
void help(Helper helper);
// <SNIP>
};
The rule of when to use includes versus forward declarations is relatively straightforward : use forward declarations when you can, and includes when you have to.
The advantage of this is clear : the less includes you have, the less dependencies there are between header files (and the more you'll speed up compilation).
Think of #include as literally including the text of the other file in this one - it's exactly the same as if you had copied it in. So in this case, the reason B and C don't need to include Helper is because you've included it in the same "compilation unit", which is what the combination of a .cpp file and all its includes is called.
With templates, a forward declaration might be enough even if the members of the forward declared type are referred to in the header file.
For example, the boost::shared_ptr<T> implementation only forward declares boost::weak_ptr<T> even though it is used in two constructors. Here is a code snipped from http://www.boost.org/doc/libs/1_47_0/boost/smart_ptr/shared_ptr.hpp:
namespace boost
{
// ...
template<class T> class weak_ptr;
// ...
template<class T> class shared_ptr
{
// ...
public:
// ...
template<class Y>
explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
{
// it is now safe to copy r.px, as pn(r.pn) did not throw
px = r.px;
}
template<class Y>
shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
{
if( !pn.empty() )
{
px = r.px;
}
}
In this case, a forward declaration of boost::weak_ptr<T> is enough since the two constructors do not get instantiated unless the definition for the forward declared boost::weak_ptr<T> has been included in the compilation unit that is using those constructors.